Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.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 2.7.12_Python_Math_Sqrt - Fatal编程技术网

平方根Python 2.7.12

平方根Python 2.7.12,python,math,sqrt,Python,Math,Sqrt,为什么数学模块返回错误的结果 第一次测试 结果 A = 12345678917 B = 12345678917 A = 123456758365483459347856 B = 123456758365483467538432 在这里,结果是正确的 第二次测试 结果 A = 12345678917 B = 12345678917 A = 123456758365483459347856 B = 123456758365483467538432 这里的结果是不正确的 为什么会这样?因为首先

为什么数学模块返回错误的结果

第一次测试 结果

A = 12345678917
B = 12345678917
A = 123456758365483459347856
B = 123456758365483467538432
在这里,结果是正确的

第二次测试 结果

A = 12345678917
B = 12345678917
A = 123456758365483459347856
B = 123456758365483467538432
这里的结果是不正确的

为什么会这样?

因为首先将数字强制转换为浮点,而浮点的尾数有限:它只能正确表示数字的一部分。所以
float(A**2)
不等于
A**2
。接下来,它计算同样近似正确的
math.sqrt

大多数使用浮点运算的函数永远不会完全正确到其整数对应项。浮点计算几乎本质上是近似的

如果计算A**2,则得到:

>>> 12345678917**2
152415787921658292889L
>>> float(12345678917**2)
1.5241578792165828e+20
现在,如果将其转换为
浮点(..)
,则会得到:

>>> 12345678917**2
152415787921658292889L
>>> float(12345678917**2)
1.5241578792165828e+20
但如果你现在问这两者是否相等:

>>> float(12345678917**2) == 12345678917**2
False
因此,在将其转换为浮点时,信息已丢失

你可以在维基百科关于浮点数如何工作的正式定义的文章中阅读更多关于浮点数如何工作以及为什么这些是近似值的信息。

声明“它提供了对C标准定义的数学函数的访问”。它还声明“除非另有明确说明,否则所有返回值都是浮点数。”

这些加在一起意味着平方根函数的参数是一个浮点值。在大多数系统中,这意味着可以容纳8个字节的浮点值,在C语言中称为“double”。您的代码在计算平方根之前将整数值转换为这样的值,然后返回这样的值

但是,8字节浮点值可以存储。这就是你在结果中得到的

如果希望平方根具有更好的精度,请使用保证整数参数具有完全精度的函数。只要做一个网络搜索,你就会找到几个。这些方法通常采用牛顿-拉斐逊方法的一种变体进行迭代,最终得到正确的答案。请注意,这比数学模块的sqrt函数要慢得多

这是我在网上修改的一个程序。我现在无法引用消息来源。此版本也适用于非整数参数,但只返回平方根的整数部分

def isqrt(x):
    """Return the integer part of the square root of x, even for very
    large values."""
    if x < 0:
        raise ValueError('square root not defined for negative numbers')
    n = int(x)
    if n == 0:
        return 0
    a, b = divmod(n.bit_length(), 2)
    x = (1 << (a+b)) - 1
    while True:
        y = (x + n//x) // 2
        if y >= x:
            return x
        x = y
def isqrt(x):
“”“返回x的平方根的整数部分,即使是非常长的
大值。”“”
如果x<0:
raise VALUERROR('未定义负数的平方根')
n=int(x)
如果n==0:
返回0
a、 b=divmod(n.位长度(),2)
x=(1=x:
返回x
x=y

如果要计算非常大的数字的sqrt,并且需要精确的结果,可以使用:


浮点数存储在内存中的方式使得使用浮点数进行计算时容易出现轻微错误,但在需要精确结果时,这些错误可能会非常严重。如其中一条注释所述,
decimal
库可以帮助您:

>>> A = Decimal(12345678917)
>>> A
Decimal('123456758365483459347856')
>>> B = A.sqrt()**2
>>> B
Decimal('123456758365483459347856.0000')
>>> A == B
True
>>> int(B)
123456758365483459347856

我使用的是3.6版,它对整数的大小没有硬编码限制。我不知道在2.7版中,将
B
转换为
int
是否会导致溢出,但无论怎样
decimal
都非常有用。

浮点精度。我知道,但如何修复它?
int(float(1234567558365483459347856))==1234567558365483459347856->False
我自己还没有试过,但是这个库可能有用吗?