假设我有两个 Python 浮点数a
,b
是否有一种简单的方法可以找出 IEEE-754 表示(或机器使用的任何表示)中两者之间有多少可表示的实数?
问问题
2110 次
4 回答
13
AFAIK,IEEE754 浮点数有一个有趣的特性。如果你有float f,那么
(*(int*)&f + 1)
在某些条件下,是下一个可表示的浮点数。所以对于浮动 a 和 b
*(int*)&a - *(int*)&b
将为您提供这些数字之间的浮点数。
有关详细信息,请参阅http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm。
于 2010-08-27T20:45:29.180 回答
12
我不知道您将使用它来做什么-但是,如果两个浮点数具有相同的指数,那应该是可能的。由于指数保持在高位,因此将浮点字节(在本例中为 8 个字节)加载为整数并从另一个字节中减去一个应该给出您想要的数字。我使用结构模型将浮点数打包为二进制表示,然后将它们解压缩为 (C, 8 字节) 长整数:
>>> 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
>>>
于 2010-08-27T20:43:15.023 回答
3
对于正数 b > a > 0,答案大约是:
(2**52) ** (log(b,2) - log(a,2))
尾数有 52 位(超过隐含的 1 ),乘以 2 得到一个指数。
所以在 [1:2) 范围内有 2**52 个数字,在 [1024:2048) 范围内
于 2010-08-27T20:38:40.237 回答
0
我会查看数学模块中的 frexp 函数。下面的示例提取尾数并将其转换为整数。差异应该是两个值之间的浮点数。
>>> math.frexp(1.1234567890)[0] * 2**53
5059599576307254.0
>>> math.frexp(1.12345678901)[0] * 2**53
5059599576352290.0
下面的代码应该做到这一点:
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
>>>
于 2010-08-27T23:49:34.913 回答