コード例 #1
0
ファイル: float.py プロジェクト: HyeockJinKim/Study-CS
    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)
コード例 #2
0
ファイル: float.py プロジェクト: HyeockJinKim/Study-CS
    def is_zero(self) -> bool:
        """
        모든 비트가 0인지 확인하는 함수
        :return: 모든 비트가 0인지 여부
        """

        return not self.sign and BitOperation.is_empty(self.exponents) and BitOperation.is_empty(self.fractions)
コード例 #3
0
ファイル: arithmetic.py プロジェクト: HyeockJinKim/Study-CS
    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
コード例 #4
0
ファイル: arithmetic.py プロジェクト: HyeockJinKim/Study-CS
 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)
コード例 #5
0
ファイル: integer.py プロジェクト: HyeockJinKim/Study-CS
    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)
コード例 #6
0
ファイル: arithmetic.py プロジェクト: HyeockJinKim/Study-CS
 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)
コード例 #7
0
ファイル: integer.py プロジェクト: HyeockJinKim/Study-CS
 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)
コード例 #8
0
ファイル: integer.py プロジェクト: HyeockJinKim/Study-CS
 def __or__(self, other: "Integer") -> "Integer":
     """
     Bit OR 연산( | )을 위한 operator overloading
     :param other: Integer 타입 가정
     :return: 새로운 Integer 객체로 return
     """
     return Integer(BitOperation.or_bits(self.bits, other.bits, self.field_len), self.sign | other.sign)
コード例 #9
0
ファイル: integer.py プロジェクト: HyeockJinKim/Study-CS
 def __and__(self, other: "Integer") -> "Integer":
     """
     Bit And 연산( & )을 위한 operator overloading
     :param other: Integer 타입 가정
     :return: 새로운 Integer 객체로 return
     """
     return Integer(BitOperation.and_bits(self.bits, other.bits, self.field_len), self.sign & other.sign)
コード例 #10
0
ファイル: integer.py プロジェクト: HyeockJinKim/Study-CS
 def char_to_dec(cls, val: str) -> list:
     """
     character 0-10의 값으로 읽음
     :param val: 0-10의 문자열
     :return: Integer 객체
     """
     return BitOperation.fit_bits(BitOperation.num_map[val], cls.field_len)
コード例 #11
0
 def val(self) -> int:
     """
     bit 들로 이루어진 값을 int 값으로 읽을 수 있도록 만드는 함수
     음수 값이 없으므로 모두 양수 읽는 것처럼 읽
     :return:
     """
     return BitOperation.binary_to_decimal(self.bits)
コード例 #12
0
 def min_value(cls) -> "UnsignedInteger":
     """
     UnsignedInteger 의 최소값
     :return: UnsignedInteger 의 최소값 0
     """
     min_list = BitOperation.empty_bits(cls.field_len)
     return UnsignedInteger(min_list)
コード例 #13
0
ファイル: arithmetic.py プロジェクト: HyeockJinKim/Study-CS
    def raw_mul_bits(a: List[Bit], b: List[Bit]) -> List[Bit]:
        """
        같은 길이의 Bit List를 곱하는 ( * ) 함수

        b Bit List의 값을 하위 비트부터 상위 비트까지 1인 비트가 있을 때마다 a bit를 left-shift하여 더함

        :param a: * 앞의 Bit List
        :param b: 곱할 Bit List
        :return: a * b의 값인 Bit List
        """
        res = BitOperation.empty_bits(len(a))
        for i, bit in enumerate(b[::-1]):
            if bit:
                mul2 = BitOperation.raw_lshift_bits(a, i)
                res, _ = Arithmetic.raw_add_bits(res, mul2)
        return res
コード例 #14
0
 def __xor__(self, other: "UnsignedInteger") -> "UnsignedInteger":
     """
     Bit XOR 연산( ^ )을 위한 operator overloading
     :param other: UnsignedInteger 타입 가정
     :return: 새로운 UnsignedInteger 객체로 return
     """
     return UnsignedInteger(BitOperation.xor_bits(self.bits, other.bits, self.field_len))
コード例 #15
0
 def __le__(self, other: "UnsignedInteger") -> bool:
     """
     Low Equal 연산 ( <= )을 위한 operator overloading
     :param other: UnsignedInteger 타입 가정
     :return: 새로운 UnsignedInteger 객체로 return
     """
     return BitOperation.le_bits(self.bits, other.bits, self.field_len)
コード例 #16
0
ファイル: integer.py プロジェクト: HyeockJinKim/Study-CS
 def __lshift__(self, num: int) -> "Integer":
     """
     num 만큼 left shift ( << ) 연산을 위한 operator overloading
     :param num: shift 하는 크기
     :return: 새로운 Integer 객체로 return
     """
     res, _ = BitOperation.lshift_bits(self.bits, num, self.field_len)
     return Integer(res)
コード例 #17
0
 def __init__(self, bits: list or str = None):
     if type(bits) == str:
         res = self.str_to_unsigned_int(bits)
         self.bits = res.bits
     elif type(bits) == list:
         self.bits = bits
     else:
         self.bits = BitOperation.empty_bits(self.field_len)
コード例 #18
0
ファイル: arithmetic.py プロジェクト: HyeockJinKim/Study-CS
    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]
コード例 #19
0
ファイル: arithmetic.py プロジェクト: HyeockJinKim/Study-CS
    def str_to_integer_until_overflow(val: str,
                                      length: int) -> (List[Bit], int):
        """
        문자열을 읽어 overflow가 발생할 때까지 Bit List를 생성하는 함수
        :param val: 숫자를 표현하는 정수 문자열
        :param length: 원하는 Bit List의 길이
        :return: 문자열 실수값에 해당하는 Bit List, 자리수
        """
        res, ten = BitOperation.equalize_bit_length(BitOperation.num_map['0'],
                                                    BitOperation.num_map['10'],
                                                    length)
        for i, c in enumerate(val):
            res = Arithmetic.raw_mul_bits(res, ten)
            res, res2 = Arithmetic.add_bits(res, BitOperation.num_map[c],
                                            length)

            if res2:
                return res, len(val) - i
        return res, length - BitOperation.first_bit_index(res) - 1
コード例 #20
0
ファイル: arithmetic.py プロジェクト: HyeockJinKim/Study-CS
    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
コード例 #21
0
ファイル: arithmetic.py プロジェクト: HyeockJinKim/Study-CS
 def mul_bits(a: List[Bit], b: List[Bit], length: int) -> List[Bit]:
     """
     Bit List의 길이를 length로 맞춘 후 값을 곱하는 ( * ) 함수
     이진수를 곱하는 함수
     raw_mul_bits 함수를 통해 계산
     :param a: * 앞의 Bit List
     :param b: 곱할 Bit List
     :param length: 원하는 Bit List의 길이
     :return: a * b의 값인 Bit List
     """
     a, b = BitOperation.equalize_bit_length(a, b, length)
     return Arithmetic.raw_mul_bits(a, b)
コード例 #22
0
ファイル: integer.py プロジェクト: HyeockJinKim/Study-CS
    def val(self) -> int:
        """
        bit 들로 이루어진 값을 int 값으로 읽을 수 있도록 만드는 함수
        음수 확인은 signed bit를 통해 확인

        테스트 및 출력을 위해 사용하는 함수
        :return: int 값으로 리턴
        """
        res = BitOperation.binary_to_decimal(self.bits)
        if self.sign:
            return -res
        return res
コード例 #23
0
ファイル: arithmetic.py プロジェクト: HyeockJinKim/Study-CS
    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
コード例 #24
0
ファイル: arithmetic.py プロジェクト: HyeockJinKim/Study-CS
 def div_bits(a: List[Bit], b: List[Bit], length: int) -> List[Bit]:
     """
     Bit List의 길이를 length로 맞춘 후 값을 나누는 ( / ) 함수
     이진수를 나누는 함수
     raw_div_bits 함수를 통해 계산
     :param a: / 앞의 Bit List
     :param b: 나눌 Bit List
     :param length: 원하는 Bit List의 길이
     :return: a / b의 값인 Bit List
     """
     a, b = BitOperation.equalize_bit_length(a, b, length)
     return Arithmetic.raw_div_bits(a, b)
コード例 #25
0
ファイル: arithmetic.py プロジェクト: HyeockJinKim/Study-CS
 def sub_bits(a: List[Bit], b: List[Bit], length: int) -> (List[Bit], Bit):
     """
     Bit List의 길이를 length로 맞춘 후 값을 빼는 ( - ) 함수
     이진수를 빼는 함수
     overflow 될 경우 overflow 값을 함께 return
     raw_sub_bits 함수를 통해 계산
     :param a: - 앞의 Bit List
     :param b: 뺄 Bit List
     :param length: 원하는 Bit List의 길이
     :return: a - b의 값인 Bit List, overflow 된 Bit
     """
     a, b = BitOperation.equalize_bit_length(a, b, length)
     return Arithmetic.raw_sub_bits(a, b)
コード例 #26
0
ファイル: arithmetic.py プロジェクト: HyeockJinKim/Study-CS
 def add_bits(a: List[Bit], b: List[Bit], length: int) -> (List[Bit], Bit):
     """
     Bit List의 길이를 length로 맞춘 후 값을 더하는 ( + ) 함수
     이진수를 더하는 함수
     overflow 될 경우 overflow 값을 함께 return
     raw_add_bits 함수를 통해 계산
     :param a: 더할 Bit List
     :param b: 더할 Bit List
     :param length: 원하는 Bit List의 길이
     :return: a + b의 값인 Bit List, overflow 된 Bit
     """
     a, b = BitOperation.equalize_bit_length(a, b, length)
     return Arithmetic.raw_add_bits(a, b)
コード例 #27
0
ファイル: arithmetic.py プロジェクト: HyeockJinKim/Study-CS
    def str_to_integer(val: str, length: int) -> List[Bit]:
        """
        문자열을 읽어 Bit List를 생성하는 함수
        10진수에서 2진수로 변환하는 함수

        :param val: 숫자를 표현하는 정수 문자열
        :param length: 원하는 Bit List의 길이
        :return: 문자열 숫자에 해당하는 Bit List
        """
        res, ten = BitOperation.equalize_bit_length(BitOperation.num_map['0'],
                                                    BitOperation.num_map['10'],
                                                    length)
        for c in val:
            res = Arithmetic.raw_mul_bits(res, ten)
            res, _ = Arithmetic.add_bits(res, BitOperation.num_map[c], length)
        return res
コード例 #28
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)
コード例 #29
0
ファイル: integer.py プロジェクト: HyeockJinKim/Study-CS
    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)
コード例 #30
0
ファイル: float.py プロジェクト: HyeockJinKim/Study-CS
    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