Example #1
0
    def is_zero(self) -> bool:
        """
        모든 비트가 0인지 확인하는 함수
        :return: 모든 비트가 0인지 여부
        """

        return not self.sign and BitOperation.is_empty(self.exponents) and BitOperation.is_empty(self.fractions)
Example #2
0
    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
Example #3
0
    def raw_div_bits(a: List[Bit], b: List[Bit]) -> List[Bit]:
        """
        같은 길이의 Bit List를 나누는 ( / ) 함수

        left-shift ( << ) 연산과 add ( + ) 연산, lower-equal ( <= ) 연산을 통해 나눗셈 구현
        상위 비트부터 하위 비트까지 값을 빼면서 몫을 구함

        :param a: / 앞의 Bit List
        :param b: 나눌 Bit List
        :return: a / b의 값인 Bit List
        """
        if BitOperation.is_empty(b):
            raise ZeroDivisionError()

        remain = BitOperation.empty_bits(len(a))
        res = BitOperation.empty_bits(len(a))
        one = BitOperation.fit_bits(BitOperation.num_map['1'], len(a))

        for i in range(len(a) - 1, -1, -1):
            first_bit = BitOperation.first_bit_index(b)
            if first_bit < i:
                continue
            div = BitOperation.raw_lshift_bits(b, i)
            sum_val, overflow = Arithmetic.raw_add_bits(remain, div)
            if overflow:
                continue
            if BitOperation.raw_le_bits(sum_val, a):
                remain, _ = Arithmetic.raw_add_bits(remain, div)
                quotient = BitOperation.raw_lshift_bits(one, i)
                res = BitOperation.raw_or_bits(res, quotient)

        return res
Example #4
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 #5
0
    def raw_add_bits(a: List[Bit], b: List[Bit]) -> (List[Bit], Bit):
        """
        같은 길이의 Bit List를 더하는 ( + ) 함수
        덧셈 결과 overflow 되었는지 여부를 함께 return

        and ( & ) 연산, xor ( ^ ) 연산과 left-shift ( << ) 연산을 통해 덧셈을 구현

        :param a: 더할 Bit List
        :param b: 더할 Bit List
        :return: a + b의 값인 Bit List, overflow 된 Bit
        """
        if BitOperation.is_empty(b):
            return a, Bit()
        carry_0 = BitOperation.raw_and_bits(a, b)
        remain = BitOperation.raw_xor_bits(a, b)
        carry = BitOperation.raw_lshift_bits(carry_0, 1)

        res, overflow = Arithmetic.raw_add_bits(remain, carry)
        return res, overflow ^ carry_0[0]
Example #6
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 #7
0
 def is_inf(self) -> bool:
     """
     값이 inf 인지 확인하는 함수
     :return: exponent가 모두 1이고 fraction은 모두 0인지 여부
     """
     return BitOperation.is_empty(BitOperation.invert_bits(self.exponents)) and BitOperation.is_empty(self.fractions)
Example #8
0
 def is_nan(self) -> bool:
     """
     값이 nan 인지 확인하는 함수
     :return: exponent가 모두 1이고 fraction은 모두 0이 아닌지 여부
     """
     return BitOperation.is_empty(BitOperation.invert_bits(self.exponents)) and not BitOperation.is_empty(self.fractions)
Example #9
0
 def is_zero(self) -> bool:
     """
     모든 비트가 0인지 확인하는 함수
     :return: 모든 비트가 0인지 여부
     """
     return not self.sign and BitOperation.is_empty(self.bits)