74 lines
2.1 KiB
Python
74 lines
2.1 KiB
Python
nums = """
|
|
0 0.001953125 0.00390625 0.005859375 0.0078125 0.009765625 0.01171875 0.013671875
|
|
0.015625 0.017578125 0.01953125 0.021484375 0.0234375 0.025390625 0.02734375 0.029296875
|
|
0.03125 0.03515625 0.0390625 0.04296875 0.046875 0.05078125 0.0546875 0.05859375
|
|
0.0625 0.0703125 0.078125 0.0859375 0.09375 0.1015625 0.109375 0.1171875
|
|
0.125 0.140625 0.15625 0.171875 0.1875 0.203125 0.21875 0.234375
|
|
0.25 0.28125 0.3125 0.34375 0.375 0.40625 0.4375 0.46875
|
|
0.5 0.5625 0.625 0.6875 0.75 0.8125 0.875 0.9375
|
|
1 1.125 1.25 1.375 1.5 1.625 1.75 1.875
|
|
2 2.25 2.5 2.75 3 3.25 3.5 3.75
|
|
4 4.5 5 5.5 6 6.5 7 7.5
|
|
8 9 10 11 12 13 14 15
|
|
16 18 20 22 24 26 28 30
|
|
32 36 40 44 48 52 56 60
|
|
64 72 80 88 96 104 112 120
|
|
128 144 160 176 192 208 224 240
|
|
"""
|
|
|
|
nums = [float(i) for i in nums.split()]
|
|
|
|
def parse_043_float(i):
|
|
get_significand = lambda i: (i >> 0) & 0b111
|
|
get_exponent = lambda i: (i >> 3) & 0b1111
|
|
# ieee_754_bias = 2 ** (4 - 1) - 1
|
|
bias = 7
|
|
|
|
exponent = get_exponent(i)
|
|
significand = get_significand(i)
|
|
|
|
base = 8
|
|
if exponent > 0:
|
|
significand |= 0b1000
|
|
else:
|
|
# denormal
|
|
if significand == 0:
|
|
significand = 0b0001
|
|
base = 16
|
|
exponent = 1
|
|
|
|
value = (significand / base) * 2 ** (exponent - bias)
|
|
return value
|
|
|
|
for i, num in enumerate(nums):
|
|
if num == 0:
|
|
continue
|
|
assert num == parse_043_float(i)
|
|
|
|
assert max(range(128)) == 127
|
|
assert min(range(128)) == 0
|
|
|
|
def find_nearest(n):
|
|
value = parse_043_float(0)
|
|
nearest = 0
|
|
nearest_diff = abs(value - n)
|
|
|
|
for i in range(1, 128):
|
|
value = parse_043_float(i)
|
|
diff = abs(value - n)
|
|
if diff < nearest_diff:
|
|
nearest = i
|
|
nearest_diff = diff
|
|
|
|
return nearest, parse_043_float(nearest)
|
|
|
|
if __name__ == "__main__":
|
|
import sys
|
|
number = sys.argv[1]
|
|
if '.' in number:
|
|
number = float(number)
|
|
print("nearest", number, *find_nearest(number))
|
|
else:
|
|
number = int(number, 10)
|
|
print(parse_043_float(number))
|