Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何避免浮点错误?_Python_Python 3.x_Floating Point_Floating Point Precision - Fatal编程技术网

Python 如何避免浮点错误?

Python 如何避免浮点错误?,python,python-3.x,floating-point,floating-point-precision,Python,Python 3.x,Floating Point,Floating Point Precision,我试图写一个近似平方根的函数(我知道有数学模块…我想自己做),但我被浮点运算搞砸了。你怎么能避免呢 def sqrt(num): root = 0.0 while root * root < num: root += 0.01 return root 我意识到我可以只使用round(),但我希望能够使它真正准确。我希望能够计算出6或7位数字。如果我是四舍五入的话,那是不可能的。我想了解如何在Python中正确处理浮点计算。这实际上与Python无关

我试图写一个近似平方根的函数(我知道有数学模块…我想自己做),但我被浮点运算搞砸了。你怎么能避免呢

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

我意识到我可以只使用
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
它实际上并不更准确,但在简单的例子中可能就不那么令人惊讶了,因为现在它正好增加了百分之一

另一种方法是坚持使用浮点数,并添加可以精确表示为二进制浮点数的内容:形式为
I/2**J
的值。例如,不是添加0.01,而是添加0.125(1/8)或0.0625(1/16)


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

我的意思是,有一些模块,比如
十进制
分数
。但是我上了一堂课,专门针对这些问题。此类仅解决加法、减法、乘法、地板除法、除法和模。但是它是易于扩展的。它基本上将浮点值转换成一个列表([浮点值,浮点值乘以10的幂得到一个整数])并从中进行算术运算。在python中,整数比浮点更精确这正是本课程所利用的。因此,不用多说,下面是代码:

class decimal():
#TODO:#优化:代码以最大限度地提高性能
"""
类十进制,一种更可靠的浮动替代方法。|v0.1
============================================================
Python的浮点(以及许多其他语言中的浮点)是
非常不准确。从外观上看可能是这样的:
.1 + .1 + .1
但在内部,它被转换成了基数2
计算机,“2到0.1的幂是多少?”
电脑说,“哦,我不知道;这是一个近似值吗
“够了吗?”
Python会说,“哦,当然,为什么不呢?我们不需要这样做
给它那么多的准确性。”
但他们擅长的是
其他一切,包括乘一个浮点数和一个
10加在一起。所以我滥用了它,做了这个:小数点
类。我们人类知道1+1+1=3。嗯,我们大多数人都知道
无论如何,这并不重要。问题是,计算机可以
太好了!此新的替换件执行以下操作:
1.查找输入的数字需要多少10^n
转换为有效的整数。
2.用原始浮点数和n(乘以
10^-n不准确)
如果你不数一数
加法、减法等算法。这比
“.1+.1+.1”。但是,它比手工打字更简单
(.1 * 100 + .01 * 100 + .1 * 100)/100
(这基本上就是这个问题的算法)但它确实有成本。
--------------------------------------------------------------------------
坏的#1:它比传统的.1+.1+.1稍慢,但是
它确实弥补了准确性
坏2:这没用,有很多库可以解决这个问题
与此相同的问题。它们的效率可能比此高或低
方法。从而使此方法变得无用。
--------------------------------------------------------------------------
差不多就这样了!谢谢你过来阅读这个文档字符串。
--------------------------------------------------------------------------
版权所有©2020 Bryan Hu
特此免费向获得许可的任何人授予许可
此软件和相关文档文件的副本
(以下简称“软件”),无限制地经营该软件,
包括但不限于使用、复制、修改、,
合并、发布、分发、再许可和/或出售
软件,并允许使用该软件的人员
按照以下条件提供:
应包括上述版权声明和本许可声明
在软件的所有副本或主要部分。
本软件按“原样”提供,不提供任何形式的明示担保
或暗示,包括但不限于
适销性、特定用途适用性和非侵权性。
在任何情况下,作者或版权持有人均不对任何
索赔、损害赔偿或其他责任,无论是在合同诉讼中,
侵权或其他行为,产生于、出于或与
软件或软件的使用或其他交易。
"""
定义初始化(自身,编号):
超级(十进制,自我)。\uuuuu init\uuuuuu()
如果编号为iter:
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')