Ejemplo n.º 1
0
 def max_value(cls) -> "Integer":
     """
     Integer 의 최대값
     :return: Integer 의 최대값 (2**32 - 1)
     """
     max_list = [Bit(True) for _ in range(cls.field_len)]
     sign = Bit()
     return Integer(max_list, sign)
Ejemplo n.º 2
0
    def inf(cls) -> "Float":
        """
        무한대 값

        :return: Infinite 값
        """

        sign = Bit()
        exponent = [Bit(True) for _ in range(cls.exponent_len)]
        fraction = [Bit() for _ in range(cls.fraction_len)]
        return Float(exponent, fraction, sign)
Ejemplo n.º 3
0
    def max_value(cls) -> "Float":
        """
        Float 의 최대값

        :return: Float 의 최대값 3.40282346639e+38
        """

        sign = Bit()
        exponent = [Bit(True) for _ in range(cls.exponent_len-1)]
        exponent.append(Bit())
        fraction = [Bit(True) for _ in range(cls.fraction_len)]
        return Float(exponent, fraction, sign)
Ejemplo n.º 4
0
    def nan(cls) -> "Float":
        """
        알 수 없는 값

        Exponent 값은 모두 1 이고 fraction이 모두 0이 아닌 값 (하나라도 1이 있음)
        :return: nan 값
        """

        sign = Bit()
        exponent = [Bit(True) for _ in range(cls.exponent_len)]
        fraction = [Bit(True) for _ in range(cls.fraction_len)]
        return Float(exponent, fraction, sign)
Ejemplo n.º 5
0
    def min_value(cls) -> "Float":
        """
        Float 의 최소값

        :return: Float 의 최소값 -1.175494490952134e-38
        """

        sign = Bit(True)
        exponent = [Bit() for _ in range(cls.exponent_len-1)]
        exponent.append(Bit(True))
        fraction = [Bit() for _ in range(cls.fraction_len-1)]
        fraction.append(Bit(True))
        return Float(exponent, fraction, sign)
Ejemplo n.º 6
0
    def _set(self, _int: int):
        """
        int 값을 통해 integer 를 받기 위한 함수

        int 값을 Bit를 통해 int로 어떻게 표현하는 지 로직 확인을 위한 함수
        deprecated
        """
        if _int < 0:
            self.sign = Bit(True)
            _int = -_int
        else:
            self.sign = Bit()
        _int = _int % self.limit
        for i, x in enumerate(self.frame):
            self.bits[i].set(bool(_int & x))
Ejemplo n.º 7
0
def test_float_multiplication5():
    float1 = Float('0.14')
    float2 = Float('0.0001')
    res = float1 * float2

    assert res.sign == Bit()
    exponents = map(lambda x: Bit(bool(x)), [0, 1, 1, 0, 1, 1, 1, 0])
    for i, exp in enumerate(exponents):
        assert res.exponents[i] == exp

    fractions = map(
        lambda x: Bit(bool(x)),
        [1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0])
    for i, exp in enumerate(fractions):
        assert res.fractions[i] == exp
Ejemplo n.º 8
0
 def max_value(cls) -> "UnsignedInteger":
     """
     UnsignedInteger 의 최대값
     :return: UnsignedInteger 의 최대값 (2**33 - 1)
     """
     max_list = [Bit(True) for _ in range(cls.field_len)]
     return UnsignedInteger(max_list)
Ejemplo n.º 9
0
 def empty_bits(length: int) -> List[Bit]:
     """
     length 길이의 비어있는 Bit List를 생성하는 함수
     :param length: 원하는 Bit List의 길이
     :return: 비어있는 length 길이의 Bit List
     """
     return [Bit() for _ in range(length)]
Ejemplo n.º 10
0
    def str_to_int(cls, val: str) -> "Integer":
        """
        String 값을 통해 integer 값 read
        :param val: String 으로 표현된 정수 값 (공백이 없다는 가정)
        :return: Integer 의 값
        """
        if val[0] == '-':
            sign = Bit(True)
            val = val[1:]
        else:
            sign = Bit()

        bits = Arithmetic.str_to_integer(val, cls.field_len)
        if len(bits) > cls.field_len:
            sign ^= bits[-cls.field_len-1]

        bits = BitOperation.fit_bits(bits, cls.field_len)
        return Integer(bits, sign)
Ejemplo n.º 11
0
 def fraction_bits(a: List[Bit]) -> List[Bit]:
     """
     float 값의 fraction에 생략된 1을 추가하는 함수
     :param a: 소수점의 유효숫자만 표현된 가수 값
     :return: 1이 추가된 가수 값
     """
     frac = a[::]
     frac.insert(0, Bit(True))
     return frac
Ejemplo n.º 12
0
    def str_to_unsigned_int(cls, val: str) -> "UnsignedInteger":
        """
        String 값을 통해 integer 값 read
        :param val: String 으로 표현된 정수 값 (공백이 없다는 가정)
        :return: UnsignedInteger 의 값
        """
        if val[0] == '-':
            sign = Bit(True)
            val = val[1:]
        else:
            sign = Bit()
        res = Arithmetic.str_to_integer(val, cls.field_len)
        res = BitOperation.fit_bits(res, cls.field_len)

        if sign:
            res, _ = Arithmetic.complement_bits(res, cls.field_len)
            return UnsignedInteger(res)
        return UnsignedInteger(res)
Ejemplo n.º 13
0
 def raw_eq_bits(a: List[Bit], b: List[Bit]) -> bool:
     """
     같은 길이의 Bit List를 값이 같은 지 ( == ) 비교
     :param a: equal 인지 확인하기 위한 BitList
     :param b: 비교 BitList
     :return: 값이 같은 지 여부
     """
     res = Bit()
     for i in range(len(a)):
         res |= (a[i] ^ b[i])
     return bool(~res)
Ejemplo n.º 14
0
 def complement_bits(a: List[Bit], length: int) -> (List[Bit], Bit):
     """
     Bit List의 2의 보수를 계산
     - 연산을 하기 위해 2의 보수 계산
     :param a: 2의 보수를 계산하는 Bit List
     :param length: 원하는 Bit List의 길이
     :return: Bit List의 2의 보수 값
     """
     a = BitOperation.fit_bits(a, length)
     a = BitOperation.invert_bits(a)
     return Arithmetic.add_bits(a, [Bit(True)], length)
Ejemplo n.º 15
0
def not_gate(a: Bit) -> Bit:
    """
    NOT Gate
    1 비트 ~ 연산을 위한 Gate
    비트 값이 1일 경우 0인 비트,
    비트 값이 0일 경우 1인 비트를 반환

    :param a: NOT Gate의 입력 비트
    :return: Not Gate의 결과 비트
    """
    return Bit(not a.val)
Ejemplo n.º 16
0
    def __le__(self, other: "Integer") -> bool:
        """
        Low Equal 연산 ( <= )을 위한 operator overloading
        :param other: Integer 타입 가정
        :return: 새로운 Integer 객체로 return
        """
        if self.sign != other.sign:
            return self.sign == Bit()

        if self.is_negative():
            return BitOperation.le_bits(other.bits, self.bits, self.field_len)
        return BitOperation.le_bits(self.bits, other.bits, self.field_len)
Ejemplo n.º 17
0
 def decomplement_bits(a: List[Bit], length: int) -> List[Bit]:
     """
     2의 보수 값을 되돌리는 함수
     signed number 값에서 연산 후 2의 보수 값을 되돌리기 위한 함수
     :param a: 2의 보수로 표현된 Bit List
     :param length: 원하는 Bit List의 길이
     :return: 2의 보수를 되돌린 Bit List 값
     """
     a = BitOperation.fit_bits(a, length)
     a, _ = Arithmetic.add_bits(a, [Bit(True) for _ in range(len(a))],
                                length)
     return BitOperation.invert_bits(a)
Ejemplo n.º 18
0
def and_gate(a: Bit, b: Bit) -> Bit:
    """
    AND Gate
    1 비트 & 연산을 위한 Gate
    a 비트의 값이 1 이면서 b 비트의 값이 1인 경우 1인 비트,
    이 외의 경우에는 0인 비트를 반환

    :param a: AND Gate의 입력 비트 1
    :param b: AND Gate의 입력 비트 2
    :return: AND Gate의 결과 비트
    """
    return Bit(a.val and b.val)
Ejemplo n.º 19
0
def or_gate(a: Bit, b: Bit) -> Bit:
    """
    OR Gate
    1 비트 | 연산을 위한 Gate
    a 비트의 값, b 비트의 값 둘 중 하나 이상의 비트가 1인 경우 1인 비트,
    이외의 경우에는 0인 비트를 반환

    :param a: OR Gate의 입력 비트 1
    :param b: OR Gate의 입력 비트 2
    :return: OR Gate의 결과 비트
    """
    return Bit(a.val or b.val)
Ejemplo n.º 20
0
    def set(self, _float: float):
        """
        float 값을 통해 float 를 받기 위한 함수

        float 값을 Bit를 통해 float로 어떻게 표현하는 지 로직 확인을 위한 함수
        deprecated
        """

        if _float < 0:
            self.sign = Bit(True)
            _float = -_float
        else:
            self.sign = Bit()

        bits = []
        int_val = int(_float)
        _float -= int_val
        while int_val > 0:
            bits.insert(0, Bit(bool(int_val % 2)))
            int_val //= 2

        del bits[0]
        exp = len(bits)
        exp = UnsignedInteger('127') + UnsignedInteger(str(exp))
        while _float > 0 and len(bits) < self.fraction_len:
            _float *= 2
            bits.append(Bit(int(_float) == 1))
            _float -= int(_float)

        for _ in range(self.fraction_len-len(bits)):
            bits.append(Bit())

        bits[-1] = Bit(bool(_float))
        self.exponents = exp.bits[-self.exponent_len:]
        self.fractions = bits[:self.fraction_len]
Ejemplo n.º 21
0
 def __init__(self, bits: list or str or int = None, sign: Bit = Bit()):
     if type(bits) == str:
         res = self.str_to_int(bits)
         self.sign = res.sign
         self.bits = res.bits
     elif type(bits) == int:
         self.sign = sign
         self.bits = BitOperation.empty_bits(self.field_len)
         self._set(bits)
     elif type(bits) == list:
         self.sign = sign
         self.bits = bits
     else:
         self.sign = sign
         self.bits = BitOperation.empty_bits(self.field_len)
Ejemplo n.º 22
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]
Ejemplo n.º 23
0
def test_unsigned_integer_max_value2():
    bits = UnsignedInteger.max_value().bits
    for bit in bits:
        assert bit == Bit(True)
Ejemplo n.º 24
0
 def __init__(self, bit_list: List[Bit] = None):
     if not bit_list:
         bit_list = [Bit() for _ in range(self.length)]
     self.bit_list = bit_list
Ejemplo n.º 25
0
def test_unsigned_integer_min_value2():
    bits = UnsignedInteger.min_value().bits
    for bit in bits:
        assert bit == Bit(False)
Ejemplo n.º 26
0
class Float:
    """
    Float의 메모리 구조
    +--------------+--------------------------+-------------------------------------------+
    | sign (1 bit) |     exponent (8 bit)     |             fraction (23 bit)             |
    +--------------+--------------------------+-------------------------------------------+

    32 bit로 이루어진 float 값

    양수 음수를 Sign bit를 통해 구분
    exponent 를 통해 소수점의 위치를 이동 (지수)
    fraction 을 통해 유효숫자를 표현 (가수)
    """
    bit_len = 32
    exponent_len = 8
    fraction_len = 23
    default_exponent_field = [Bit() for _ in range(exponent_len)]
    default_fraction_field = [Bit() for _ in range(fraction_len)]

    def __init__(self, exponents: list or float or int or str = None, fractions: list = None, sign: Bit = Bit()):
        if type(exponents) == str:
            res = self.str_to_float(exponents)
            self.sign = res.sign
            self.exponents = res.exponents
            self.fractions = res.fractions
        elif type(exponents) == float or type(exponents) == int:
            self.sign = sign
            self.exponents = self.default_exponent_field[::]
            self.fractions = self.default_fraction_field[::]
            self.set(exponents)
        elif type(exponents) == list:
            self.sign = sign
            self.exponents = exponents
            self.fractions = fractions
        else:
            self.sign = sign
            self.exponents = self.default_exponent_field[::]
            self.fractions = self.default_fraction_field[::]

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

        return not self.sign and BitOperation.is_empty(self.exponents) and BitOperation.is_empty(self.fractions)

    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)

    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)

    @classmethod
    def max_value(cls) -> "Float":
        """
        Float 의 최대값

        :return: Float 의 최대값 3.40282346639e+38
        """

        sign = Bit()
        exponent = [Bit(True) for _ in range(cls.exponent_len-1)]
        exponent.append(Bit())
        fraction = [Bit(True) for _ in range(cls.fraction_len)]
        return Float(exponent, fraction, sign)

    @classmethod
    def min_value(cls) -> "Float":
        """
        Float 의 최소값

        :return: Float 의 최소값 -1.175494490952134e-38
        """

        sign = Bit(True)
        exponent = [Bit() for _ in range(cls.exponent_len-1)]
        exponent.append(Bit(True))
        fraction = [Bit() for _ in range(cls.fraction_len-1)]
        fraction.append(Bit(True))
        return Float(exponent, fraction, sign)

    @classmethod
    def inf(cls) -> "Float":
        """
        무한대 값

        :return: Infinite 값
        """

        sign = Bit()
        exponent = [Bit(True) for _ in range(cls.exponent_len)]
        fraction = [Bit() for _ in range(cls.fraction_len)]
        return Float(exponent, fraction, sign)

    @classmethod
    def nan(cls) -> "Float":
        """
        알 수 없는 값

        Exponent 값은 모두 1 이고 fraction이 모두 0이 아닌 값 (하나라도 1이 있음)
        :return: nan 값
        """

        sign = Bit()
        exponent = [Bit(True) for _ in range(cls.exponent_len)]
        fraction = [Bit(True) for _ in range(cls.fraction_len)]
        return Float(exponent, fraction, sign)

    def set(self, _float: float):
        """
        float 값을 통해 float 를 받기 위한 함수

        float 값을 Bit를 통해 float로 어떻게 표현하는 지 로직 확인을 위한 함수
        deprecated
        """

        if _float < 0:
            self.sign = Bit(True)
            _float = -_float
        else:
            self.sign = Bit()

        bits = []
        int_val = int(_float)
        _float -= int_val
        while int_val > 0:
            bits.insert(0, Bit(bool(int_val % 2)))
            int_val //= 2

        del bits[0]
        exp = len(bits)
        exp = UnsignedInteger('127') + UnsignedInteger(str(exp))
        while _float > 0 and len(bits) < self.fraction_len:
            _float *= 2
            bits.append(Bit(int(_float) == 1))
            _float -= int(_float)

        for _ in range(self.fraction_len-len(bits)):
            bits.append(Bit())

        bits[-1] = Bit(bool(_float))
        self.exponents = exp.bits[-self.exponent_len:]
        self.fractions = bits[:self.fraction_len]

    @classmethod
    def str_to_float(cls, val: str) -> "Float":
        """
        String 값을 통해 float 값 read
        :param val: String 으로 표현된 정수 값 (공백이 없다는 가정)
        :return: Float 의 값
        """

        if val[0] == '-':
            sign = Bit(True)
            val = val[1:]
        else:
            sign = Bit()
        dec, minor = cls.split_point(val)
        fraction, digit = Arithmetic.str_to_integer_until_overflow(dec, cls.fraction_len+1)
        frac, digit = Arithmetic.str_to_minor(fraction, minor, digit, cls.fraction_len+1)

        fraction = frac[1:]
        if str(digit)[0] == '-':
            exponent, _ = Arithmetic.sub_bits(
                Arithmetic.str_to_integer('127', cls.exponent_len),
                Arithmetic.str_to_integer(str(digit)[1:], cls.exponent_len),
                cls.exponent_len
            )
        else:
            exponent, _ = Arithmetic.add_bits(
                Arithmetic.str_to_integer('127', cls.exponent_len),
                Arithmetic.str_to_integer(str(digit), cls.exponent_len),
                cls.exponent_len
            )
        return Float(exponent, fraction, sign)

    @classmethod
    def split_point(cls, val: str) -> (str, str):
        """
        문자열을 . 을 기준으로 정수값과 소수값을 나눔
        :param val: 실수값 문자열
        :return: 정수값, 소수값
        """
        val = val.split('.')
        if len(val) < 2:
            return val[0], '0'
        return val[0], val[1]

    def val(self) -> float:
        """
        bit 들로 이루어진 값을 float 값으로 읽을 수 있도록 만드는 함수
        음수 확인은 signed bit를 통해 확인

        테스트 및 출력을 위해 사용하는 함수
        :return: float 값으로 리턴
        """

        if self.is_zero():
            return 0

        if self.is_nan():
            return float('nan')

        if self.is_inf():
            if self.sign:
                return -float('inf')
            return float('inf')

        res = BitOperation.binary_to_float(self.exponents, self.fractions)
        if self.sign:
            return -res
        return res

    def __str__(self) -> str:
        return str(self.val())

    def is_negative(self) -> Bit:
        """
        Sign 비트를 통해 음수 확인
        :return: 음수인지 여부
        """
        return self.sign

    def __neg__(self) -> "Float":
        """
        sign minus 연산( - )을 위한 operator overloading
        :return: 새로운 Float 객체로 return
        """
        return Float(self.exponents[::], self.fractions[::], ~self.sign)

    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 __sub__(self, other: "Float") -> "Float":
        """
        Binary Sub 연산 ( - )을 위한 operator overloading
        음수로 변경한 후 add 연산
        :param other: Float 타입 가정
        :return: 새로운 Float 객체로 return
        """
        return self + (-other)

    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 __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)

    def __le__(self, other: "Float") -> bool:
        """
        Low Equal 연산 ( <= )을 위한 operator overloading
        :param other: Float 타입 가정
        :return: 새로운 Float 객체로 return
        """
        pass

    def __eq__(self, other: "Float") -> bool:
        return self.sign == other.sign and BitOperation.eq_bits(self.exponents, other.exponents, self.exponent_len) and\
               BitOperation.eq_bits(self.fractions, other.fractions, self.fraction_len)
Ejemplo n.º 27
0
class BitOperation:
    num_map = {
        '0': [],
        '1': [Bit(True)],
        '2': [Bit(True), Bit()],
        '3': [Bit(True), Bit(True)],
        '4': [Bit(True), Bit(), Bit()],
        '5': [Bit(True), Bit(), Bit(True)],
        '6': [Bit(True), Bit(True), Bit()],
        '7': [Bit(True), Bit(True), Bit(True)],
        '8': [Bit(True), Bit(), Bit(), Bit()],
        '9': [Bit(True), Bit(), Bit(), Bit(True)],
        '10': [Bit(True), Bit(), Bit(True), Bit()],
    }

    @staticmethod
    def equalize_bit_length(a: List[Bit], b: List[Bit],
                            length: int) -> (List[Bit], List[Bit]):
        """
        입력받은 두 Bit List의 길이를 length 길이로 만듦
        :param a: length 길이로 맞출 Bit List
        :param b: length 길이로 맞출 Bit List
        :param length: 원하는 Bit List의 길이
        :return: length 길이의 a, b
        """
        a = BitOperation.fit_bits(a, length)
        b = BitOperation.fit_bits(b, length)
        return a, b

    @staticmethod
    def eq_bits(a: List[Bit], b: List[Bit], length: int) -> bool:
        """
        두 Bit List의 길이를 length 길이로 맞춘 뒤 같은 지 ( == ) 비교
        raw_eq_bits 함수를 통해 비교
        :param a: equal 인지 확인하기 위한 BitList
        :param b: 비교 BitList
        :param length: 원하는 Bit List의 길이
        :return: 값이 같은 지 여부
        """
        a, b = BitOperation.equalize_bit_length(a, b, length)
        return BitOperation.raw_eq_bits(a, b)

    @staticmethod
    def raw_eq_bits(a: List[Bit], b: List[Bit]) -> bool:
        """
        같은 길이의 Bit List를 값이 같은 지 ( == ) 비교
        :param a: equal 인지 확인하기 위한 BitList
        :param b: 비교 BitList
        :return: 값이 같은 지 여부
        """
        res = Bit()
        for i in range(len(a)):
            res |= (a[i] ^ b[i])
        return bool(~res)

    @staticmethod
    def le_bits(a: List[Bit], b: List[Bit], length: int) -> bool:
        """
        두 Bit List의 길이를 length 길이로 맞춘 뒤 a가 작거나 같은 지 ( <= ) 비교
        raw_le_bits 함수를 통해 비교
        :param a: less-equal 인지 확인하기 위한 BitList
        :param b: 비교 BitList
        :param length: 원하는 Bit List의 길이
        :return: 값이 작거나 같은지 여부
        """
        a, b = BitOperation.equalize_bit_length(a, b, length)
        return BitOperation.raw_le_bits(a, b)

    @staticmethod
    def raw_le_bits(a: List[Bit], b: List[Bit]) -> bool:
        """
        같은 길이의 Bit List 중 a가 작거나 같은 지 ( <= ) 비교
        :param a: less-equal 인지 확인하기 위한 BitList
        :param b: 비교 BitList
        :return: 값이 작거나 같은지 여부
        """
        for i in range(len(a)):
            if a[i] > b[i]:
                return False
            if b[i] > a[i]:
                return True
        return True

    @staticmethod
    def ge_bits(a: List[Bit], b: List[Bit], length: int) -> bool:
        """
        두 Bit List의 길이를 length 길이로 맞춘 뒤 a가 크거나 같은 지 ( >= ) 비교
        raw_ge_bits 함수를 통해 비교
        :param a: greater-equal 인지 확인하기 위한 BitList
        :param b: 비교 BitList
        :param length: 원하는 Bit List의 길이
        :return: 값이 크거나 같은 지 여부
        """
        a, b = BitOperation.equalize_bit_length(a, b, length)
        return BitOperation.raw_ge_bits(a, b)

    @staticmethod
    def raw_ge_bits(a: List[Bit], b: List[Bit]) -> bool:
        """
        같은 길이의 Bit List 중 a가 크거나 같은 지 ( >= ) 비교
        :param a: greater-equal 인지 확인하기 위한 BitList
        :param b: 비교 BitList
        :return: 값이 크거나 같은 지 여부
        """
        for i in range(len(a)):
            if a[i] > b[i]:
                return True
            if b[i] > a[i]:
                return False
        return True

    @staticmethod
    def and_bits(a: List[Bit], b: List[Bit], length: int) -> List[Bit]:
        """
        Bit List의 길이를 같게 만든 후 And ( & ) 연산
        raw_and_bits 함수를 통해 연산
        :param a: And 연산을 수행할 Bit List
        :param b: And 연산을 수행할 Bit List
        :param length: 원하는 Bit List의 길이
        :return: And 연산 결과 Bit List
        """
        a, b = BitOperation.equalize_bit_length(a, b, length)
        return BitOperation.raw_and_bits(a, b)

    @staticmethod
    def raw_and_bits(a: List[Bit], b: List[Bit]) -> List[Bit]:
        """
        Bit List 의 And ( & ) 연산
        :param a: And 연산을 수행할 Bit List
        :param b: And 연산을 수행할 Bit List
        :return: And 연산 결과 Bit List
        """
        return [a[i] & b[i] for i in range(len(a))]

    @staticmethod
    def xor_bits(a: List[Bit], b: List[Bit], length: int) -> List[Bit]:
        """
        Bit List의 길이를 같게 만든 후 Xor ( ^ ) 연산
        raw_xor_bits 함수를 통해 연산
        :param a: Xor 연산을 수행할 Bit List
        :param b: Xor 연산을 수행할 Bit List
        :param length: 원하는 Bit List의 길이
        :return: Xor 연산 결과 Bit List
        """
        a, b = BitOperation.equalize_bit_length(a, b, length)
        return BitOperation.raw_xor_bits(a, b)

    @staticmethod
    def raw_xor_bits(a: List[Bit], b: List[Bit]) -> List[Bit]:
        """
        Bit List 의 Xor ( ^ ) 연산
        :param a: Xor 연산을 수행할 Bit List
        :param b: Xor 연산을 수행할 Bit List
        :return: Xor 연산 결과 Bit List
        """
        return [a[i] ^ b[i] for i in range(len(a))]

    @staticmethod
    def or_bits(a: List[Bit], b: List[Bit], length: int) -> List[Bit]:
        """
        Bit List의 길이를 같게 만든 후 Or ( | ) 연산
        raw_or_bits 함수를 통해 연산
        :param a: Or 연산을 수행할 Bit List
        :param b: Or 연산을 수행할 Bit List
        :param length: 원하는 Bit List의 길이
        :return: Or 연산 결과 Bit List
        """
        a, b = BitOperation.equalize_bit_length(a, b, length)
        return BitOperation.raw_or_bits(a, b)

    @staticmethod
    def raw_or_bits(a: List[Bit], b: List[Bit]) -> List[Bit]:
        """
        Bit List 의 Or ( | ) 연산
        :param a: Or 연산을 수행할 Bit List
        :param b: Or 연산을 수행할 Bit List
        :return: Or 연산 결과 Bit List
        """
        return [a[i] | b[i] for i in range(len(a))]

    @staticmethod
    def lshift_bits(a: List[Bit], index: int or List[Bit],
                    length: int) -> List[Bit]:
        """
        Bit List의 길이를 length 길이로 만든 후 left-shift ( << ) 연산
        index를 Bit List 값일 경우 shift 연산을 위해 int 값으로 변경
        raw_lshift_bits 함수 이용
        :param a: left-shift 연산할 Bit List
        :param index: left-shift 할 크기
        :param length: 원하는 Bit List의 길이
        :return: index 크기만큼 left-shift 한 Bit List
        """
        if type(index) == list:
            index = BitOperation.binary_to_decimal(index)

        a = BitOperation.fit_bits(a, length)
        return BitOperation.raw_lshift_bits(a, index)

    @staticmethod
    def raw_lshift_bits(a: List[Bit], index: int) -> List[Bit]:
        """
        Bit List를 left-shift ( << ) 연산
        :param a: left-shift 연산할 Bit List
        :param index: left-shift 할 크기
        :return: index 크기만큼 left-shift 한 Bit List
        """
        bits = BitOperation.empty_bits(len(a))
        bits[:len(a) - index] = a[index:]
        return bits

    @staticmethod
    def rshift_bits(a: List[Bit], index: int or List[Bit],
                    length: int) -> List[Bit]:
        """
        Bit List의 길이를 length 길이로 만든 후 right-shift ( >> ) 연산
        index를 Bit List 값일 경우 shift 연산을 위해 int 값으로 변경
        raw_rshift_bits 함수 이용
        :param a: right-shift 연산할 Bit List
        :param index: right-shift 할 크기
        :param length: 원하는 Bit List의 길이
        :return: index 크기만큼 right-shift 한 Bit List
        """
        if type(index) == list:
            index = BitOperation.binary_to_decimal(index)

        a = BitOperation.fit_bits(a, length)
        return BitOperation.raw_rshift_bits(a, index)

    @staticmethod
    def raw_rshift_bits(a: List[Bit], index: int) -> List[Bit]:
        """
        Bit List를 right-shift ( >> )연산
        :param a: right-shift 연산할 Bit List
        :param index: right-shift 할 크기
        :return: index 크기만큼 right-shift 한 Bit List
        """
        bits = BitOperation.empty_bits(len(a))
        bits[index:] = a[:len(a) - index]
        return bits

    @staticmethod
    def fraction_bits(a: List[Bit]) -> List[Bit]:
        """
        float 값의 fraction에 생략된 1을 추가하는 함수
        :param a: 소수점의 유효숫자만 표현된 가수 값
        :return: 1이 추가된 가수 값
        """
        frac = a[::]
        frac.insert(0, Bit(True))
        return frac

    @staticmethod
    def invert_bits(a: List[Bit]) -> List[Bit]:
        """
        Bit List에 invert ( ~ ) 연산
        Bit List의 모든 Bit의 값을 반대로 뒤집음
        :param a: invert 연산할 Bit List
        :return: invert 연산된 Bit List
        """
        return [~bit for bit in a]

    @staticmethod
    def fit_bits(a: List[Bit], length: int) -> List[Bit]:
        """
        Bit List를 length 길이로 만듦
        length 보다 길 경우 뒤에서부터 length 길이로 자르고
        length 보다 짧을 경우 0을 앞에 추가함

        :param a: length 길이로 만들 Bit List
        :param length: 원하는 Bit List의 길이
        :return: length 길이의 Bit List
        """
        if len(a) >= length:
            return a[-length:]
        if len(a) == length:
            return a[::]

        empty = BitOperation.empty_bits(length)
        for i in range(1, len(a) + 1):
            empty[-i] = a[-i]
        return empty

    @staticmethod
    def is_empty(a: List[Bit]) -> bool:
        """
        Bit List의 모든 Bit 가 0인지 확인
        :param a: 모든 Bit 가 0인지 확인할 함수
        :return: 모든 Bit 가 0인지 여부
        """
        if not a:
            return True
        return not reduce(lambda x, y: x | y, a)

    @staticmethod
    def empty_bits(length: int) -> List[Bit]:
        """
        length 길이의 비어있는 Bit List를 생성하는 함수
        :param length: 원하는 Bit List의 길이
        :return: 비어있는 length 길이의 Bit List
        """
        return [Bit() for _ in range(length)]

    @staticmethod
    def binary_to_decimal(a: List[Bit]) -> int:
        """
        입력받은 Bit List의 값을 읽어 int로 변환하는 함수
        python 의 기능을 실행시키기 위해 int로 변환할 때 사용 ( << 연산 등 )
        :param a: int 값을 확인하기 위한 Bit List
        :return: Bit List에 해당하는 int 값
        """
        res = 0
        frame = 1
        for bit in a[::-1]:
            if bit:
                res += frame
            frame <<= 1
        return res

    @staticmethod
    def binary_to_float(exp: List[Bit], fraction: List[Bit]) -> float:
        """
        입력받은 exponent와 fraction을 읽어 float값으로 변환하는 함수
        :param exp: exponent (지수) 값
        :param fraction: fraction (가수) 값
        :return: 가수 * 2 ^ 지수
        """
        res = 0
        exp = BitOperation.binary_to_decimal(exp) - 127 - len(fraction)
        frame = 2**exp
        for bit in fraction[::-1]:
            if bit:
                res += frame
            frame *= 2
        res += frame
        return res

    @staticmethod
    def first_bit_index(a: List[Bit]) -> int:
        """
        Bit List에서 첫 1의 위치를 찾는 함수
        없을 경우 Bit List의 길이 값을 return
        :param a: 첫 1의 위치를 찾을 Bit List
        :return: 첫 1의 위치
        """
        for i in range(len(a)):
            if a[i]:
                return i
        return len(a)
Ejemplo n.º 28
0
 def __init__(self, exponents: list or float or int or str = None, fractions: list = None, sign: Bit = Bit()):
     if type(exponents) == str:
         res = self.str_to_float(exponents)
         self.sign = res.sign
         self.exponents = res.exponents
         self.fractions = res.fractions
     elif type(exponents) == float or type(exponents) == int:
         self.sign = sign
         self.exponents = self.default_exponent_field[::]
         self.fractions = self.default_fraction_field[::]
         self.set(exponents)
     elif type(exponents) == list:
         self.sign = sign
         self.exponents = exponents
         self.fractions = fractions
     else:
         self.sign = sign
         self.exponents = self.default_exponent_field[::]
         self.fractions = self.default_fraction_field[::]
Ejemplo n.º 29
0
class ControlSignal(enum.Enum):
    NOT = [Bit(), Bit(), Bit(), Bit()]                 # 0
    AND = [Bit(), Bit(), Bit(), Bit(True)]             # 1
    NAND = [Bit(), Bit(), Bit(True), Bit()]            # 2
    OR = [Bit(), Bit(), Bit(True), Bit(True)]          # 3
    NOR = [Bit(), Bit(True), Bit(), Bit()]             # 4
    XOR = [Bit(), Bit(True), Bit(), Bit(True)]         # 5
    XNOR = [Bit(), Bit(True), Bit(True), Bit()]        # 6
    INC = [Bit(), Bit(True), Bit(True), Bit(True)]     # 7
    DEC = [Bit(True), Bit(), Bit(), Bit()]             # 8
    MINUS = [Bit(True), Bit(), Bit(), Bit(True)]       # 9
    ADD = [Bit(True), Bit(), Bit(True), Bit()]         # 10
    SUB = [Bit(True), Bit(), Bit(True), Bit(True)]     # 11
    LSHIFT = [Bit(True), Bit(True), Bit(), Bit()]      # 12
    RSHIFT = [Bit(True), Bit(True), Bit(), Bit(True)]  # 13