Number of floats between two floats

后端 未结 4 1917
一整个雨季
一整个雨季 2021-02-20 03:41

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 representati

相关标签:
4条回答
  • 2021-02-20 03:44

    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
    >>>
    
    0 讨论(0)
  • 2021-02-20 03:52

    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.

    0 讨论(0)
  • 2021-02-20 04:03

    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)

    0 讨论(0)
  • 2021-02-20 04:08

    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 讨论(0)
提交回复
热议问题