Number of floats between two floats

扶醉桌前 提交于 2019-12-05 01:31:23

I don'tknow what you will be using this for - but, if both floats have the same exponent, it should be possible. As the exponent is kept on the high order bits, loading the float bytes (8 bytes in this case) as an integer and subtracting one from another should give the number you want. I use the struct model to pack the floats to a binary representation, and then unpack those as (C, 8 byte) long ints:

>>> import struct
>>> a = struct.pack("dd", 1.000000,1.000001)
>>> b = struct.unpack("ll",a)
>>> b[1] - b[0]
4503599627
>>> a = struct.pack("dd", 1.000000000,1.000000001)
>>> b = struct.unpack("ll",a)
>>> b[1] - b[0]
4503600
>>>

AFAIK, IEEE754 floats have an interesting property. If you have float f, then

(*(int*)&f + 1)

under certain conditions, is the next representable floating point number. So for floats a and b

*(int*)&a - *(int*)&b

Will give you the amount of floating point numbers between those numbers.

See http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm for more information.

For positive numbers b > a > 0, the answer is approximately:

(2**52) ** (log(b,2) - log(a,2))

There are 52 bits of mantissa ( past the implied 1 ), multiplied by 2 raised to an exponent.

So there are 2**52 numbers in range [1:2) as in the range [1024:2048)

I would look at the frexp function in the math module. The example below extracts the mantissa and converts it to an integer. The difference should be the number of floats between to the two values.

>>> math.frexp(1.1234567890)[0] * 2**53
5059599576307254.0
>>> math.frexp(1.12345678901)[0] * 2**53
5059599576352290.0

The following code should do it:

import math
import sys

def delta(x,y):
    '''Return the number of floats between x and y.'''
    x = float(x)
    y = float(y)
    if x == y:
        return 0
    elif x < y:
        return -delta(y,x)
    else:
        x_mant, x_exp = math.frexp(x)
        y_mant, y_exp = math.frexp(y)
        x_int = int(x_mant * 2**(sys.float_info.mant_dig + x_exp - y_exp))
        y_int = int(y_mant * 2**sys.float_info.mant_dig)
        return x_int - y_int

print(delta(1.123456789, 1.1234567889999))
450
>>>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!