Skip to content

Instantly share code, notes, and snippets.

@fikr4n
Last active January 20, 2025 03:42
Show Gist options
  • Save fikr4n/0e19642db8fa6bbcdddb8d47adda0e0a to your computer and use it in GitHub Desktop.
Save fikr4n/0e19642db8fa6bbcdddb8d47adda0e0a to your computer and use it in GitHub Desktop.
Convert float to/from string to illustrate/understand how a double precision floating-point number is encoded based on IEEE 754
#!/usr/bin/env python3
import struct
def to_float(bins):
"""
Convert a binary string to float.
"""
def _expand(s, length):
ei = s.find('..')
if ei == -1: return s
d = length - len(s) + 2
return s[:ei] + (d * s[ei - 1]) + s[(ei + 2):]
sign, exp, mantissa = (i.replace('_', '') for i in bins.split())
exp = _expand(exp, 11)
mantissa = _expand(mantissa, 52)
if len(sign) != 1 or len(exp) != 11 or len(mantissa) != 52:
raise ValueError((sign, exp, mantissa))
int64 = (int(sign, 2) << 63) | (int(exp, 2) << 52) | int(mantissa, 2)
return struct.unpack('>d', struct.pack('>Q', int64))[0]
def to_bin(floatv, grouplen=8):
"""
Convert a float to binary string grouped per `grouplen` digits.
"""
def _group(s, w):
rem = len(s) % -w
return '_'.join(s[max(0, i):i + w] for i in range(rem, len(s), w))
s = ''.join(format(i, '08b') for i in struct.pack('>d', floatv))
return f"{s[0]} {_group(s[1:12], grouplen)} {_group(s[12:], grouplen)}"
def to_sn2(floatv):
"""
Convert a float to string representing the float in scientific notation
with base 2.
"""
def _superscript(s):
m = {'0': '⁰', '1': '¹', '2': '²', '3': '³', '4': '⁴', '5': '⁵',
'6': '⁶', '7': '⁷', '8': '⁸', '9': '⁹', '-': '⁻'}
return ''.join(m[i] for i in s)
int64 = struct.unpack('>Q', struct.pack('>d', floatv))[0]
sign = '+' if int64 >> 63 == 0 else '-'
mantissa = (int64 & 4503599627370495) / (1 << 52)
exp = (int64 >> 52) & 2047
if exp == 2047: return str(floatv)
elif exp == 0: exp = -1022
else: exp -= 1023; mantissa += 1
return f"{sign}{mantissa} × 2{_superscript(str(exp))}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment