Example #1
0
    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)
Example #2
0
    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
Example #3
0
    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)