-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcbm_to_float.py
52 lines (33 loc) · 1.58 KB
/
cbm_to_float.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# this was generated by ChatGPT and I'm not sure if it is correct.
# It looks OK but errors might be subtle.
#
# the wiki states:
# Mantissa: (m4 >= 128 ? -1 : +1) * ((m4 | 0x80) >> 8 + m3 >> 16 + m2 >> 24 + m1 >> 32)
# as a C-language like expression, with "x >> y" as "float multiply x by 2↑(-y)" (right-bit-shift operation)
def cbm_float_to_python_float(hex_bytes):
# Ensure we have exactly 5 bytes
if len(hex_bytes) != 5:
raise ValueError("CBM float requires exactly 5 bytes")
# Extract the exponent and bias it by subtracting 128
exponent = hex_bytes[0] - 128
# Extract the mantissa as a 4-byte integer
mantissa = (hex_bytes[1] << 24) | (hex_bytes[2] << 16) | (hex_bytes[3] << 8) | hex_bytes[4]
# The sign bit is in the MSB of the mantissa; 0 means positive, 1 means negative
sign = -1 if (mantissa & 0x80000000) else 1
mantissa |= 0x80000000
#print(bin(mantissa), hex(mantissa))
# Convert mantissa to a float by dividing by 2**31 (to match the fixed point range)
float_value = sign * (mantissa / (2**32)) * (2 ** exponent)
return float_value
z = cbm_float_to_python_float([0x80, 0x00, 0x00, 0x00, 0x00])
assert z == 0.5, z
z = cbm_float_to_python_float([0x81, 0x00, 0x00, 0x00, 0x00])
assert z == 1.0, z
z = cbm_float_to_python_float([0x81, 0x80, 0x00, 0x00, 0x00])
assert z == -1.0, z
cbm_hex = [0x98, 0x35, 0x44, 0x7a, 0x00]
def convert(cbm_hex):
result = cbm_float_to_python_float(cbm_hex)
print("Converted CBM float to Python float:", result)
import sys
convert(([int(n, 16) for n in sys.argv[1:]] + [0x00] * 5)[:5])