问题在Increment a python floating point value by the smallest possible amount差异中没有解决:
1. **[Increment a python floating point value by the smallest possible amount][1] just not works try this code**:
import math
epsilon = math.ldexp(1.0, -53) # smallest double that 0.5+epsilon != 0.5
maxDouble = float(2**1024 - 2**971) # From the IEEE 754 standard
minDouble = math.ldexp(1.0, -1022) # min positive normalized double
smallEpsilon = math.ldexp(1.0, -1074) # smallest increment for doubles < minFloat
infinity = math.ldexp(1.0, 1023) * 2
def nextafter(x,y):
"""returns the next IEEE double after x in the direction of y if possible"""
if y==x:
return y #if x==y, no increment
# handle NaN
if x!=x or y!=y:
return x + y
if x >= infinity:
return infinity
if x <= -infinity:
return -infinity
if -minDouble < x < minDouble:
if y > x:
return x + smallEpsilon
else:
return x - smallEpsilon
m, e = math.frexp(x)
if y > x:
m += epsilon
else:
m -= epsilon
return math.ldexp(m,e)
print nextafter(1e307, 1e308), 'nextafter(1e307, 1e308)'
print nextafter(1e308, 1e307), 'nextafter(1e308, 1e307)'
结果无效:
1e+307 nextafter(1e307, 1e308) # invalid 2e307 possible!!!
1e+308 nextafter(1e308, 1e307) # invalid 9e307 possible!!!
没有询问如何添加/减去最小值,但被问及如何在特定方向上添加/减去值 - 建议解决方案需要知道x和y。这里只需知道x。 2.建议Increment a python floating point value by the smallest possible amount中的解决方案不适用于边境条件。
我想为任何浮点数添加/减去一些最小值,这会将此浮点值改为大约mantissa/significant part的一位。如何有效地计算这么小的数字。
例如我有x:
这样的数组xs = [1e300, 1e0, 1e-300]
生成最小值的功能是什么?所有断言都应该有效。
for x in xs:
assert x < x + smallestChange(x)
assert x > x - smallestChange(x)
考虑1e308 + 1 == 1e308
因为1
对尾数的确意味着0
所以`smallestChange'应该是动态的。
答案 0 :(得分:0)
尝试使用hex:
>>> float.hex(3740.0)
'0x1.d380000000000p+11'
编辑十六进制字符串并:
>>> float.fromhex('0x1.d380000000001p+11')
3740.0000000000005
这使用了文档中示例的反向。
更长的答案:
n = 1e+300
h = float.hex(n)
print h
i = h.find('.')
if i < 0:
print h, 'is not a float'
else:
j = h.find('p')
n1 = int(h[i+1:j], base=16)
a = n
while a == n:
n1 += 1
a = float.fromhex(h[:i+1] + hex(n1)[2:j-i+1] + h[j:])
print a-n