关于python:复数的小数位数精度

您所在的位置:网站首页 复数的中位数怎么算 关于python:复数的小数位数精度

关于python:复数的小数位数精度

2024-07-09 19:50| 来源: 网络整理| 查看: 265

考虑以下Python代码,该代码对Python中的复数执行一些简单的算术运算:

123456789101112import numpy as np s = 2 l = 5 v = np.array([np.exp(1j*2*np.pi/l)]) A = pow(s*v, l) + s*v #Print the precision of np.complex128 print np.finfo(np.complex128).precision #Export using 20 decimal places for real and imaginary parts np.savetxt('A.csv', A, fmt=['%.20e%+.20ej'], delimiter=',')

我看到了这个答案,以便在Python中打印np.complex128变量的精度,得到的结果是15。当我在Spyder中检查A的值时,我看到(32.61803398874989+1.9021130325903035j)的虚部具有超过15个小数位。另外,导出的CSV文件的值为3.26180339887498931262e+01+1.90211303259030350965e+00j 其实部和虚部均具有20个有用的小数位。

我在这里感到困惑:如果精度为15,那多余的小数位数是多少?根据这里,np.complex128由两个64位浮点数组成,一个为实数部分,另一个为虚数部分。

但是我的主要问题是我在程序中对复数(例如加法,乘法和矩阵求逆)进行了许多此类运算,每次运行时,都会得到不同的结果,有时是正确的,有时是错误的。看来我的程序对这些操作的准确性非常敏感。如何用Python量化复杂数字的精度,我能得到的最大值是多少?

我正在使用Python 2.7.14和Numpy 1.14.3。

相关讨论 您只是如何"检查Spyder中A的值"? 有很多方法可以做到这一点。 @RoryDaulton我只使用了变量资源管理器并双击了该变量。

一个完整的答案将需要很多空间。首先,您需要阅读一本有关数值分析的书,其中解释了二进制浮点类型是如何工作和存储的。但是这里有一些部分解释。

64位浮点值以二进制而不是十进制存储。因此,有关十进制数字的大多数说法必须是近似值,而不是全部内容。

当np.finfo(np.complex128).precision(或其他任何东西)说有15位有效的十进制数字时,这意味着您不能指望超过这15位数字。这是一个示例,取自我的IPython控制台。

12345In [4]: 9.000000000000001 Out[4]: 9.000000000000002 In [5]: 9.000000000000001 == 9.000000000000002 Out[5]: True

Python默认情况下对带小数点的任何数字使用64位浮点类型,将这两个16位小数数字视为相同。使用数字9.000000000000001时,只能保证前15个十进制数字正确存储。此后的所有操作均无法保证,在这种情况下,您会看到1基本上已更改为2。

有时您可以获得的位数不超过15个十进制数字。例如,由于数字是以二进制形式存储的,因此,比1.0更大的数字在小数点后将具有比9.0更大的二进制数字。这是因为9使用4个二进制数字,而1仅使用1个数字,因此在基数点之后可以再使用3个二进制数字。因此,让我们看一下数字的虚部1.9021130325903035:

12345678In [17]: 1.902113032590303 == 1.9021130325903035 Out[17]: False In [18]: 1.9021130325903036 == 1.9021130325903035 Out[18]: True In [19]: 1.902113032590304 == 1.9021130325903035 Out[19]: False

我们看到,尽管数字显示17位十进制数字,但是当我们将最后一位数字从5更改为6时,Python却看不到变化。但是,如果我们将该数字四舍五入为16个十进制数字(向上或向下),则会发生变化。因此,我们可以说该数字存储为16位十进制数字,甚至更多。这就是为什么当我解释精度时,我说的是保证浮点数可以包含15个有效十进制数字,但可以有16个数字,而实际精度则略高于此数字。简而言之,有15或16个有效十进制数字。

Python有两种打印浮点数的基本方法:str函数和repr函数。 str函数可以简单地打印内容,因此用户无需太多细节就可以理解结果。 repr函数提供了更多细节,并尝试打印太多细节,以至于存储的数据可以完全由打印内容请注意,在某些情况下,例如在控制台中键入数字值,或者如您所见,在Spyder中使用变量资源管理器,将看不见使用repr。

当Spyder或Python在您的数字1.9021130325903035上执行repr时,它会提供足够的数字来完全定义数字。正如我们在上面看到的,如果它只显示16个十进制数字,并删除最后一个5,则结果将与存储的结果略有不同。因此,Python输出一个额外的数字,以便您可以知道值是什么。如果Python打印了最终的6而不是5,则该值将是相同的,但是如果Python完全省略了该数字,则该值将被更改。因此,通过repr进行的Python错误地给出了太多的数字。尽管打印了17位数字,但是只有16位是确定的。

最后,由于np.savetxt命令中的%.20e指示符,您告诉Python显示20个十进制数字,因此csv文件显示了20个十进制数字。不管您写了什么,那20个十进制数字都不都是"有用的小数位"。在虚部中,仅前16个或17个有用,这取决于定义"有用"的方式。 Python基本上将二进制位(全零)添加到存储的值中,并将其打印为20个十进制数字。但是那些零二进制位未存储在该值中。

相关讨论 我明白你的意思,但我有些怀疑。当我说"有用的"小数位时,是指在CSV上打印的多余数字非零,因此根据您的回答,因为实际值保持不变,因此可以假定它们是随机数。但是,为什么要声称它们为零? 我没有声称打印出来的那些多余的十进制数字是零;我声称附加到存储值的多余二进制数字为零。换句话说,Python假装存储的浮点值正确,并打印出前20个十进制数字。用所有十进制数字打印的虚部的精确值是1.9021130325903035096501980660832487046718597412109375,它具有53个十进制数字。 (我使用了decimal模块来获取它。)CSV得到了它的前20个十进制数字。这些添加的数字不是"随机数"。 好吧,我明白了。但是,我的算法有时会起作用。确切地说,在算法过程中我对4×4复Vandermonde矩阵的行进行了24个置换。在该算法中,所有排列都应给出相同的最终结果。我不会弄乱细节,但事实是,对于某些排列而言,它是可行的,对于某些排列而言,它却没有。我几乎可以肯定,它是一个精度问题,也许是在那些有问题的情况下计算逆时。您知道我是否可以提高Python中复数和/或复杂运算的精度吗? @mgus:在Python中执行扩展浮点精度的常用方法是decimal模块,但这仅用于实数,而不用于复数。 mpmath模块执行"任意精度的实数和复数浮点运算"。它不包含在标准Python中,但默认情况下已包含并安装在Python的Anaconda安装中(这是我使用的)。您可能想检查一下矩阵求逆例程-有很多,有些精度比其他精度更高。根据其功能列表,mpmath确实可以进行矩阵求逆。 我还有一个问题。您通常从哪里开始计算那15个保证基数的数量?这是1000.123456789123456,1.000123456789123456e3的2个示例。这些数字是完全相同的,但是即使我将倒数第二个更改为第一个数字,我的Python也会打印出相同的数字。我对这15个小数点非常困惑。看来这里并不能保证。 @mgus:在这种情况下,要对(十进制)数字进行计数,请对数字中出现的所有数字进行计数,并忽略小数点以及e处或之后的任何数字(如果存在的话)。因此,您最后一条评论中的两个数字都有19个十进制数字。前16位是有效数字,因为您的第一个数字是1,第17位数字对存储的数字没有完全有效的影响,但是第18和19位数字绝对不是有效的。这就是为什么您可以在不更改值的情况下更改"第二到最后一位数字"(即第18位数字)的原因。 好吧,您能推荐我一本书,讨论浮点数的二进制表示形式吗?我想使自己熟悉这些想法。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3