假设我有两个Python浮点a
和b
,是否有一种简单的方法可以找出IEEE-754表示中两者之间有多少可表示的实数(或者机器使用的任何表示形式)正在使用)?
答案 0 :(得分:12)
AFAIK,IEEE754花车有一个有趣的属性。如果你有浮动f,那么
(*(int*)&f + 1)
在某些条件下,是下一个可表示的浮点数。因此对于花车a和b
*(int*)&a - *(int*)&b
将为您提供这些数字之间的浮点数。
有关详细信息,请参阅http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm。
答案 1 :(得分:10)
我不知道你将使用它 - 但是,如果两个浮点数具有相同的指数,那么应该是可能的。由于指数保持在高位上,因此将浮点字节(在本例中为8个字节)作为整数加载并从另一个中减去一个应该得到您想要的数字。我使用struct模型将浮点数打包成二进制表示,然后将它们解压缩为(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
>>>
答案 2 :(得分:3)
对于正数b> a> 0,答案是大约:
(2**52) ** (log(b,2) - log(a,2))
有52位尾数(超过隐含的1),乘以2加到指数。
因此范围[1:2]中有2 ** 52个数字,范围为[1024:2048]
答案 3 :(得分:0)
我会看一下math模块中的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
>>>