def __mul__(self, other: "Float") -> "Float": """ Binary Mul 연산 ( * )을 위한 operator overloading :param other: Float 타입 가정 :return: 새로운 Float 객체로 return """ a_frac = BitOperation.fraction_bits(self.fractions) b_frac = BitOperation.fraction_bits(other.fractions) exp, _ = Arithmetic.add_bits(self.exponents, other.exponents, self.exponent_len) bias = Arithmetic.str_to_integer('127', self.exponent_len) exp, _ = Arithmetic.raw_sub_bits(exp, bias) extra = BitOperation.empty_bits(self.fraction_len + 1) mul = a_frac over = BitOperation.empty_bits(self.fraction_len + 1) for bit in b_frac[:0:-1]: if bit: extra, overflow = Arithmetic.raw_add_bits(extra, mul) if overflow: over, _ = Arithmetic.add_bits(over, BitOperation.num_map['1'], self.fraction_len+1) mul = BitOperation.raw_lshift_bits(mul, 1) if BitOperation.is_empty(mul): break res = BitOperation.empty_bits(self.fraction_len + 1) mul = a_frac for bit in b_frac: if bit: res, overflow = Arithmetic.raw_add_bits(res, mul) if overflow: res = BitOperation.raw_rshift_bits(res, 1) res[0] = overflow exp, _ = Arithmetic.add_bits(exp, BitOperation.num_map['1'], self.exponent_len) mul = BitOperation.raw_rshift_bits(mul, 1) mul = BitOperation.raw_rshift_bits(mul, 1) if BitOperation.is_empty(mul): break res, _ = Arithmetic.raw_add_bits(res, over) res = res[1:] return Float(exp, res, self.sign ^ other.sign)
def shift_fraction(a_exp: List[Bit], b_exp: List[Bit], b_frac: List[Bit]): """ float의 exponent 값 차이만큼 shift 한 fraction 값 연산 right-shift 연산 할 때 생략된 값이 있을 때 1을 더함 :param a_exp: 비교하는 exponent :param b_exp: 비교하는 exponent :param b_frac: shift 연산할 fraction :return: shift 연산 된 fraction """ diff, _ = Arithmetic.raw_sub_bits(a_exp, b_exp) diff = BitOperation.binary_to_decimal(diff) b_fraction = BitOperation.raw_rshift_bits(b_frac, diff) if not BitOperation.is_empty(b_frac[:diff]): b_fraction, _ = Arithmetic.add_bits(b_fraction, BitOperation.num_map['1'], len(b_fraction)) return b_fraction return b_fraction
def __truediv__(self, other: "Float") -> "Float": """ Binary Div 연산 ( / )을 위한 operator overloading :param other: Float 타입 가정 :return: 새로운 Float 객체로 return """ if other.is_zero(): if self.is_zero(): return self.nan() if self.sign ^ other.sign: return -self.inf() return self.inf() remain = BitOperation.fraction_bits(self.fractions) div = BitOperation.fraction_bits(other.fractions) exp, _ = Arithmetic.sub_bits(self.exponents, other.exponents, self.exponent_len) bias = Arithmetic.str_to_integer('127', self.exponent_len) exp, _ = Arithmetic.raw_add_bits(exp, bias) res = BitOperation.empty_bits(self.fraction_len+1) one = BitOperation.fit_bits(BitOperation.num_map['1'], self.fraction_len+1) for i in range(self.fraction_len, -1, -1): if BitOperation.raw_ge_bits(remain, div): remain, _ = Arithmetic.raw_sub_bits(remain, div) quotient = BitOperation.raw_lshift_bits(one, i) res = BitOperation.raw_or_bits(res, quotient) remain = BitOperation.raw_lshift_bits(remain, 1) else: div = BitOperation.raw_rshift_bits(div, 1) if BitOperation.first_bit_index(res) != 0: res = BitOperation.raw_lshift_bits(res, 1) exp, _ = Arithmetic.sub_bits(exp, BitOperation.num_map['1'], self.exponent_len) return Float(exp, res[1:], self.sign ^ other.sign)