具有表示错误的四舍五入浮动到最接近和正确的结果
Rounding floats with representation error to the closest and correct result
我遇到了 Python 中的经典 representation error 开始出现问题的情况:我需要将它们用于 Numpy 中的矩阵运算和 decimal 类型还不被支持。
你们都知道如果我111.85 * 111.85
我会得到12510.422499999999
但是如果我round(12510.422499999999, 4)
我可以得到正确的结果当然是12510.4225
.
但实际问题是:
- 这个回合是个好主意和好做法吗?
- 这对所有情况都有效吗?有时 ..999 小数点的小数点位置可能更多
- 最后,如何获得适当的小数位数以用于所有可能值的舍入?
这里真正的问题是首先要确定表示错误是如何开始成为问题的。
您不应该使用 human-readable 打印浮点数的表示,您应该使用例如 str.format
或其他一些表示方法。
将您的数字保留为所有计算的数字(无论您使用浮点数还是小数或其他...)并且只在演示时舍入或截断。
即使您将数字四舍五入,小数点仍然不会完全符合您的预期。 Python 可能只显示最高有效位,但潜在的十进制不准确仍然存在。
python 文档 devote a section to it
Many users are not aware of the approximation because of the way
values are displayed. Python only prints a decimal approximation to
the true decimal value of the binary approximation stored by the
machine. On most machines, if Python were to print the true decimal
value of the binary approximation stored for 0.1, it would have to
display
>>> 0.1
0.1000000000000000055511151231257827021181583404541015625
That is more digits than most people find useful, so Python keeps the
number of digits manageable by displaying a rounded value instead
>>> 1 / 10
0.1
对于大多数用例,可以安全地忽略不准确性。如果你是
处理极小或极大的数字或需要
精确到许多小数位,你可以使用 decimal
图书馆
>>> Decimal('111.85') * Decimal('111.85')
Decimal('12510.4225')
我遇到了 Python 中的经典 representation error 开始出现问题的情况:我需要将它们用于 Numpy 中的矩阵运算和 decimal 类型还不被支持。
你们都知道如果我111.85 * 111.85
我会得到12510.422499999999
但是如果我round(12510.422499999999, 4)
我可以得到正确的结果当然是12510.4225
.
但实际问题是:
- 这个回合是个好主意和好做法吗?
- 这对所有情况都有效吗?有时 ..999 小数点的小数点位置可能更多
- 最后,如何获得适当的小数位数以用于所有可能值的舍入?
这里真正的问题是首先要确定表示错误是如何开始成为问题的。
您不应该使用 human-readable 打印浮点数的表示,您应该使用例如 str.format
或其他一些表示方法。
将您的数字保留为所有计算的数字(无论您使用浮点数还是小数或其他...)并且只在演示时舍入或截断。
即使您将数字四舍五入,小数点仍然不会完全符合您的预期。 Python 可能只显示最高有效位,但潜在的十进制不准确仍然存在。
python 文档 devote a section to it
Many users are not aware of the approximation because of the way values are displayed. Python only prints a decimal approximation to the true decimal value of the binary approximation stored by the machine. On most machines, if Python were to print the true decimal value of the binary approximation stored for 0.1, it would have to display
>>> 0.1 0.1000000000000000055511151231257827021181583404541015625
That is more digits than most people find useful, so Python keeps the number of digits manageable by displaying a rounded value instead
>>> 1 / 10 0.1
对于大多数用例,可以安全地忽略不准确性。如果你是 处理极小或极大的数字或需要 精确到许多小数位,你可以使用 decimal 图书馆
>>> Decimal('111.85') * Decimal('111.85')
Decimal('12510.4225')