pistache
pistache

Reputation: 6203

Discrepancy of floating representation

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

Upvotes: 1

Views: 102

Answers (1)

user149341
user149341

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

Related Questions