如何在不使用小数、分数或任何其他外部库的情况下修复浮点数中的 Python 舍入错误?
How to fix Python rounding error in Floating Point numbers without using decimal, fractions or any other external libraries?
我有一个 class 模拟器:
class Simulator: # we use a class just to hold variables between calls
def __init__(self):
# initialise accumulators
self.a_sum = 0
self.b_sum = 0
def update(self, a, b):
# increment
self.a_sum += a
self.b_sum += b
def results(self):
# return a pair of results
return self.a_sum, self.a_sum - self.b_sum
如果我打印结果
a_error, d_error = simulate(Simulator())
print(f"Error in a_sum is {a_error} and {d_error} in d_sum")
我得到Error in a_sum is 13.7734375 and 4.101232676410264e-08 in d_sum
,这是使用浮点数造成的。我知道计算是如何进行的,但我想知道是否可以在不转换为十进制的情况下修复错误?我试过四舍五入:
def update(self, a, b):
# increment
self.a_sum += round(a, 3)
self.b_sum += round(b, 3)
它得到了稍微低一些的错误:Error in a_sum is 5.375 and 4.101232676410264e-08 in d_sum
但在那之后我再也无法得到它了。
有什么想法吗?
如何在不使用小数、分数或任何其他外部库的情况下修复浮点数中的 Python 舍入错误?
Floating Point Arithmetic: Issues and Limitations
(...)there are many different decimal numbers that share the same
nearest approximate binary fraction. For example, the numbers 0.1
and
0.10000000000000001
and
0.1000000000000000055511151231257827021181583404541015625
are all
approximated by 3602879701896397 / 2 ** 55
. Since all of these
decimal values share the same approximation, any one of them could be
displayed while still preserving the invariant eval(repr(x)) == x
.(...)this is in the very nature of binary floating-point: this is
not a bug in Python, and it is not a bug in your code either. You’ll
see the same kind of thing in all languages that support your
hardware’s floating-point arithmetic (although some languages may not
display the difference by default, or in all output modes).
强调由我添加,所以我想在这种情况下修复 float
的唯一方法是根本不使用 float
。如果没有 decimal、fractions 或任何其他外部库.
,这通常是不可行的
我有一个 class 模拟器:
class Simulator: # we use a class just to hold variables between calls
def __init__(self):
# initialise accumulators
self.a_sum = 0
self.b_sum = 0
def update(self, a, b):
# increment
self.a_sum += a
self.b_sum += b
def results(self):
# return a pair of results
return self.a_sum, self.a_sum - self.b_sum
如果我打印结果
a_error, d_error = simulate(Simulator())
print(f"Error in a_sum is {a_error} and {d_error} in d_sum")
我得到Error in a_sum is 13.7734375 and 4.101232676410264e-08 in d_sum
,这是使用浮点数造成的。我知道计算是如何进行的,但我想知道是否可以在不转换为十进制的情况下修复错误?我试过四舍五入:
def update(self, a, b):
# increment
self.a_sum += round(a, 3)
self.b_sum += round(b, 3)
它得到了稍微低一些的错误:Error in a_sum is 5.375 and 4.101232676410264e-08 in d_sum
但在那之后我再也无法得到它了。
有什么想法吗?
如何在不使用小数、分数或任何其他外部库的情况下修复浮点数中的 Python 舍入错误?
Floating Point Arithmetic: Issues and Limitations
(...)there are many different decimal numbers that share the same nearest approximate binary fraction. For example, the numbers
0.1
and0.10000000000000001
and0.1000000000000000055511151231257827021181583404541015625
are all approximated by3602879701896397 / 2 ** 55
. Since all of these decimal values share the same approximation, any one of them could be displayed while still preserving the invarianteval(repr(x)) == x
.(...)this is in the very nature of binary floating-point: this is not a bug in Python, and it is not a bug in your code either. You’ll see the same kind of thing in all languages that support your hardware’s floating-point arithmetic (although some languages may not display the difference by default, or in all output modes).
强调由我添加,所以我想在这种情况下修复 float
的唯一方法是根本不使用 float
。如果没有 decimal、fractions 或任何其他外部库.