|
| 1 | + |
| 2 | + |
| 3 | +class HalfPrecision: |
| 4 | + |
| 5 | + __BIAS = 15 |
| 6 | + |
| 7 | + def __init__(self, number: float): |
| 8 | + if type(number)!=float: |
| 9 | + raise TypeError("Please enter a float") |
| 10 | + if number > 65504: |
| 11 | + self.string_representation = "0111110000000000" |
| 12 | + return |
| 13 | + if number == float('inf'): |
| 14 | + self.string_representation = "0111110000000000" |
| 15 | + return |
| 16 | + elif number == float('-inf'): |
| 17 | + self.string_representation = "1111110000000000" |
| 18 | + return |
| 19 | + binary_representation = str(BinaryRepresentation(number)) |
| 20 | + sign_bit = '1' if binary_representation[0] == '-' else '0' |
| 21 | + abs_binary = binary_representation.replace("-", "") |
| 22 | + dot_index = abs_binary.index('.') |
| 23 | + exponent: int |
| 24 | + if abs_binary.startswith('1'): |
| 25 | + exponent = dot_index - 1 |
| 26 | + else: |
| 27 | + decimal = abs_binary.partition('.')[2] |
| 28 | + if decimal.find('1') == -1: |
| 29 | + self.string_representation = "0000000000000000" \ |
| 30 | + if sign_bit == '0' else "1000000000000000" |
| 31 | + return |
| 32 | + else: |
| 33 | + exponent = -(decimal.index('1') + 1) |
| 34 | + biased = float(exponent + HalfPrecision.__BIAS) |
| 35 | + exponent_bits = BinaryRepresentation(biased).integer2binary() |
| 36 | + while len(exponent_bits) < 5: |
| 37 | + exponent_bits = '0' + exponent_bits |
| 38 | + ind_1 = abs_binary.index('1') |
| 39 | + ment = abs_binary[ind_1 + 1:] |
| 40 | + ment = ment.replace('.', '') |
| 41 | + length = len(ment) |
| 42 | + if length < 10: |
| 43 | + while len(ment) < 10: |
| 44 | + ment += '0' |
| 45 | + elif length > 10: |
| 46 | + ment = ment[:10] |
| 47 | + self.string_representation = sign_bit + exponent_bits + ment |
| 48 | + |
| 49 | + |
| 50 | + def __str__(self): |
| 51 | + return self.string_representation |
| 52 | + |
| 53 | + |
| 54 | + |
| 55 | + |
| 56 | +class BinaryRepresentation: |
| 57 | + |
| 58 | + def __init__(self, number: float): |
| 59 | + if not isinstance(number, float): |
| 60 | + raise TypeError('number is not a float') |
| 61 | + self.negative = True if str(number)[0] == '-' else False |
| 62 | + self.number = abs(number) |
| 63 | + |
| 64 | + def integer2binary(self): |
| 65 | + num_int = int(self.number) |
| 66 | + if num_int == 0: |
| 67 | + return "0" |
| 68 | + arr = [] |
| 69 | + while num_int > 0: |
| 70 | + arr.append(num_int % 2) |
| 71 | + num_int = num_int // 2 |
| 72 | + arr.reverse() |
| 73 | + return self.int_array_to_string(arr) |
| 74 | + |
| 75 | + def decimal2binary(self): |
| 76 | + num_dec = self.number - int(self.number) |
| 77 | + arr = [] |
| 78 | + loop_count = 1 |
| 79 | + while loop_count < 25: |
| 80 | + if num_dec == 0: |
| 81 | + break |
| 82 | + num_dec *= 2 |
| 83 | + int_part = int(num_dec) |
| 84 | + arr.append(int_part) |
| 85 | + if int_part == 1: |
| 86 | + num_dec -= int_part |
| 87 | + loop_count += 1 |
| 88 | + return self.int_array_to_string(arr) |
| 89 | + |
| 90 | + def __str__(self): |
| 91 | + prefix = "-" if self.negative else "" |
| 92 | + return prefix + self.integer2binary() + "." + self.decimal2binary() |
| 93 | + |
| 94 | + @staticmethod |
| 95 | + def int_array_to_string(arr) -> str: |
| 96 | + result = '' |
| 97 | + for i in arr: |
| 98 | + result += str(i) |
| 99 | + return result |
| 100 | + |
0 commit comments