开发者

Number of floats between two floats

开发者 https://www.devze.com 2023-01-13 17:19 出处:网络
Say I have two Python floats a and b, is there an easy way to find out how many representable real numbers are between the two in IEEE-754 representation (or whatever representation the machine used i

Say I have two Python floats a and b, is there an easy way to find out how many representable real numbers are between the two in IEEE-754 representation (or whatever representation the machine used i开发者_如何学JAVAs using)?


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.


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
>>>


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
>>>
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号