def str_to_minor(real: List[Bit], val: str, digit: int, length: int) -> (List[Bit], int): """ 소수점 아래의 값을 표현하는 문자열을 읽어 Bit List를 생성하는 함수 :param real: 소수점 위의 값의 Bit List :param val: 소수점 아래의 값을 표현하는 문자열 :param digit: 소수점 위의 자리수 :param length: 원하는 Bit List의 길이 :return: 문자열 실수값에 해당하는 Bit List, 자리수 """ real, ten = BitOperation.equalize_bit_length( real, BitOperation.num_map['10'], length) base = BitOperation.fit_bits(BitOperation.num_map['1'], length) twenty = BitOperation.raw_lshift_bits(ten, 1) remain = BitOperation.empty_bits(length) shift = 1 index = 0 while True: if index < len(val) and index < 6: remain = Arithmetic.raw_mul_bits(remain, twenty) next_digit = BitOperation.lshift_bits( BitOperation.num_map[val[index]], shift, length) remain, _ = Arithmetic.raw_add_bits(remain, next_digit) index += 1 shift += 1 base = Arithmetic.raw_mul_bits(base, ten) else: remain = BitOperation.raw_lshift_bits(remain, 1) if BitOperation.is_empty(BitOperation.raw_or_bits( remain, real)): return real, -127 real = BitOperation.raw_lshift_bits(real, 1) if BitOperation.raw_ge_bits(remain, base): real, _ = Arithmetic.add_bits(real, BitOperation.num_map['1'], length) remain, _ = Arithmetic.sub_bits(remain, base, length) if BitOperation.first_bit_index(real) == 0: remain = BitOperation.raw_lshift_bits(remain, 1) if BitOperation.raw_ge_bits(remain, base): real = BitOperation.or_bits(real, BitOperation.num_map['1'], length) break elif BitOperation.is_empty(real): digit -= 1 return real, digit
def __add__(self, other: "Float") -> "Float": """ Binary Add 연산 ( + )을 위한 operator overloading exponent를 같은 값으로 만든 후 fraction 덧셈 연산 :param other: Float 타입 가정 :return: 새로운 Float 객체로 return """ exp, a_frac, b_frac = Arithmetic.equalize_exponent(self.exponents, self.fractions, other.exponents, other.fractions) if BitOperation.raw_ge_bits(a_frac, b_frac): sign = self.sign else: sign = other.sign if self.sign ^ other.sign: res, overflow = Arithmetic.sub_bits(a_frac, b_frac, self.fraction_len+1) if sign: res = Arithmetic.decomplement_bits(res, self.fraction_len+1) else: res, overflow = Arithmetic.add_bits(a_frac, b_frac, self.fraction_len+1) if overflow: res.insert(0, overflow) res = res[:-1] exp, _ = Arithmetic.add_bits(exp, BitOperation.num_map['1'], self.exponent_len) first = BitOperation.first_bit_index(res) if first != 0: res, _ = Arithmetic.add_bits(res, BitOperation.num_map['1'], self.fraction_len + 1) exp, _ = Arithmetic.raw_sub_bits(exp, Arithmetic.str_to_integer(str(first), self.exponent_len)) frac = BitOperation.raw_lshift_bits(res, first)[1:] return Float(exp, frac, sign)
def equalize_exponent(a_exp: List[Bit], a_frac: List[Bit], b_exp: List[Bit], b_frac: List[Bit]): """ 두 float 값의 exponent 값이 같게 만들고 fraction을 조정함 :param a_exp: a의 exponent ( 지수 ) :param a_frac: a의 fraction ( 가수 ) :param b_exp: b의 exponent ( 지수 ) :param b_frac: b의 fraction ( 가수 ) :return: 같은 exponent, exponent에 맞춰 조정된 a의 fraction, exponent에 맞춰 조정된 b의 fraction """ a_frac = BitOperation.fraction_bits(a_frac) b_frac = BitOperation.fraction_bits(b_frac) if BitOperation.raw_ge_bits(a_exp, b_exp): b_frac = Arithmetic.shift_fraction(a_exp, b_exp, b_frac) exp = a_exp else: a_frac = Arithmetic.shift_fraction(b_exp, a_exp, a_frac) exp = b_exp return exp, a_frac, b_frac
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)