python - 如何避免浮点错误?

标签 python python-3.x floating-point floating-point-precision

我试图编写一个函数来近似平方根(我知道有数学模块......我想自己做),但我被浮点运算搞砸了。如何避免这种情况?

def sqrt(num):
    root = 0.0
    while root * root < num:
        root += 0.01
    return root

使用它会产生以下结果:

>>> sqrt(4)
2.0000000000000013
>>> sqrt(9)
3.00999999999998

我意识到我可以使用round() ,但我希望能够使其非常准确。我希望能够计算出 6 或 7 位数字。如果我四舍五入的话这是不可能的。我想了解如何在 Python 中正确处理浮点计算。

最佳答案

这实际上与 Python 无关 - 您会在使用硬件的二进制浮点算术的任何语言中看到相同的行为。第一 read the docs .

读完后,您将更好地理解您没有在代码中添加百分之一。这正是您要添加的内容:

>>> from decimal import Decimal
>>> Decimal(.01)
Decimal('0.01000000000000000020816681711721685132943093776702880859375')

该字符串显示二进制浮点(C 中的“ double ”)的精确十进制值,近似于精确的十进制值 0.01。您真正要添加的内容比 1/100 稍大一些。

控制 float 值误差是一个称为“数值分析”的领域,是一个非常庞大和复杂的主题。只要您对 float 只是十进制值的近似值感到惊讶,就可以使用 decimal 模块。这将为您消除一个充满“肤浅”问题的世界。例如,对您的函数进行这个小修改:

from decimal import Decimal as D

def sqrt(num):
    root = D(0)
    while root * root < num:
        root += D("0.01")
    return root

然后:

>>> sqrt(4)
Decimal('2.00')
>>> sqrt(9)
Decimal('3.00')

它并不是真的更准确,但在简单的示例中可能并不那么令人惊讶,因为现在它恰好增加了百分之一。

另一种方法是坚持使用 float ,并添加一些可以完全表示为二进制 float 的东西:I/2**J 形式的值。例如,不要添加 0.01,而是添加 0.125 (1/8) 或 0.0625 (1/16)。

然后查找“牛顿法”来计算平方根;-)

关于python - 如何避免浮点错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52731171/

相关文章:

python - 在 jsonlines/nd json 中编辑一行

Python svgwrite 模块背景色

python - Matplotlib 动画不接受圆形补丁作为 fargs

c++ - 如何聚合 float 组并使用可并行化方法获得精确结果?

python - django order_by 查询集,升序和降序

Python 3 列表切片引发索引错误

python - Python 的数字字典

python - 如何使用 python 日志配置将参数传递给自定义日志格式化程序?

c - 我用 pow(10,2) 和 pow(10,j), j=2; 得到了不同的结果;

python - 更多 cttypes c_float() 精度