当前位置: 首页 > 面试题库 >

如何避免浮点错误?

司空均
2023-03-14
问题内容

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

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无关-
使用硬件的二进制浮点算法,您会在任何语言中看到相同的行为。首先阅读文档。

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

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

该字符串显示二进制浮点数的精确十进制值(C中的“双精度”),精确到十进制值0.01。您真正添加的东西比1/100大。

控制浮点数值错误是一个称为“数值分析”的字段,它是一个非常大而复杂的主题。只要您对浮点数仅是十进制值的近似值感到震惊,请使用该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')

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

另一种选择是坚持使用浮点数,然后添加一些
精确表示为二进制浮点数的值:form的值I/2**J。例如,代替添加0.01,而添加0.125(1/8)或0.0625(1/16)。

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



 类似资料:
  • 以下是输出: 为什么我得到的是而不是?我知道这与浮点错误有关,但我无法把握为什么它正在发生,以及我应该做些什么来防止这种情况的发生(如果有办法的话)。有人能解释一下(或者给我指一个链接)会帮助我理解吗?欢迎任何输入。谢谢!

  • 问题内容: 我正在尝试使用一些UI按钮将位置移动0.1或-0.1来影响3D模型的转换。 我的模型位置是一个三维浮点数,因此简单地向其中一个值添加0.1f会导致明显的舍入误差。虽然我可以使用BigDecimal之类的东西来保持精度,但我仍然必须将其从浮点数转换为最后的浮点数,并且它始终会产生愚蠢的数字,这使我的UI看起来一团糟。 我可以将显示的值设为漂亮,但是舍入错误只会随着更多的编辑而变得更糟,它

  • 我正在将oracle从10升级到12,对于这个特定的项目,我遇到了以下错误: 似乎它没有识别我在DataSource上添加的配置: 我们使用的是Java 8,我们对代码有这些依赖关系: 问题是它正在为另一个项目工作(与这个项目具有相同的结构,但由于某种原因它在这里不起作用) 是否有任何遗漏或我可以找到问题并解决问题的地方?

  • 本文向大家介绍如何避免JS浮点运算的精度问题(例:0.1+0.7=0.7999999999999999)相关面试题,主要包含被问及如何避免JS浮点运算的精度问题(例:0.1+0.7=0.7999999999999999)时的应答技巧和注意事项,需要的朋友参考一下 可以利用,默认最多保留3位有效小数

  • 问题内容: 我用option运行pytest 。 不幸的是,这会打印出很多点。例: 有没有办法避免这么长的点和“ s”字符列表? 更新资料 有一个有效的答案。但是不知何故对我来说太长了。我现在使用此解决方法:我将其添加到调用pytest的脚本中: 问题答案: 详细选项无法关闭测试结果打印。但是,可以通过多种方式进行自定义,包括结果打印。要更改此设置,您将覆盖该挂钩。 关闭短字母 创建一个具有以下内

  • 问题内容: 我正在尝试通过从客户端向服务器发送密钥和随机数来认证用户。 我的代码未向我显示客户端的响应。执行下面的代码时,我得到了一个空指针异常。 问题答案: 解决大多数问题的固定步骤: 阅读堆栈跟踪以确定哪一行代码引发NPE 在该行代码处设置一个断点 使用调试器,在遇到断点时,确定该行中的对象引用是 弄清楚为什么引用该文件(到目前为止,这是唯一实际的困难部分) 解决根本原因(也可能很困难)