Reputation: 6203
In this SO answer, an user provided this short function that returns the binary representation of a floating-point value:
import struct
import sys
def float_to_bin(f):
""" Convert a float into a binary string. """
if sys.version_info >= (3,): # Python 3?
ba = struct.pack('>d', f)
else:
ba = bytearray(struct.pack('>d', f)) # Convert str result.
s = ''.join('{:08b}'.format(b) for b in ba)
return s[:-1].lstrip('0') + s[0] # Strip but one leading zero.
When I call this function with the value 7/3-4/3
(in Python 3.5), or with 1.0000000000000002
, I get this binary representation :
11111111110000000000000000000000000000000000000000000000000000
Using this online tool, with the same values, I get this binary representation :
11111111110000000000000000000000000000000000000000000000000001
float_to_bin
returning the floating representation of 1.0
for 1.0000000000000002
? float_to_bin
induced somewhere (maybe when calling struct.pack
) ?Upvotes: 1
Views: 102
Reputation:
The logic in that function to "strip but one leading zero" is completely wrong, and is removing significant digits from the result.
The correct representation of the value is neither of the values mentioned in your question; it is:
0011111111110000000000000000000000000000000000000000000000000001
which can be retrieved by replacing the last line of that function with:
return s
or by using the simpler implementation:
def float_to_bin(f):
[d] = struct.unpack(">Q", struct.pack(">d", f))
return '{:064b}'.format(d)
Leading and trailing zeroes in floating-point values are significant, and cannot be removed without altering the value.
Upvotes: 4