当前位置: 首页 > 知识库问答 >
问题:

为什么是数学。sqrt()对于大数字不正确?

巫马嘉祯
2023-03-14

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

A = 12345678917
print 'A =',A
B = sqrt(A**2)
print 'B =',int(B)

结果

A = 12345678917
B = 12345678917

在这里,结果是正确的。

A = 123456758365483459347856
print 'A =',A
B = sqrt(A**2)
print 'B =',int(B)

结果

A = 123456758365483459347856
B = 123456758365483467538432

这里的结果是不正确的。

为什么会这样呢?

共有3个答案

敖涵容
2023-03-14

如果要计算真正大的数字的sqrt,并且需要精确的结果,可以使用symphy

import sympy

num = sympy.Integer(123456758365483459347856)

print(int(num) == int(sympy.sqrt(num**2)))
井浩思
2023-03-14

数学模块的留档状态为"它提供对C标准定义的数学函数的访问。"它还指出“除非另有明确说明,否则所有返回值都是浮点数。”

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

但是,8字节浮点值最多可以存储15到17位有效十进制数字。这就是你在结果中得到的。

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

因为数学。sqrt(…)首先将数字强制转换为浮点数,浮点数的尾数有限:它只能正确表示数字的一部分。所以float(A**2)不等于A**2。接下来,它计算数学。sqrt也大致正确。

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

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

>>> 12345678917**2
152415787921658292889L

现在,如果将其转换为浮点(…) ,一个得到:

>>> float(12345678917**2)
1.5241578792165828e+20

但是如果你现在问这两者是否相等:

>>> float(12345678917**2) == 12345678917**2
False

因此,在将其转换为浮动时,信息已经丢失。

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

 类似资料:
  • 我想检查一个数字是否是正方形,一个数字是否是三角形。问题发生在sqrt(num)上,它为我测试的所有数字返回0 我正在使用一个在线编译器,尝试了几个编译器,所以这不是一个编译问题。尝试将num声明为double和int,结果相同 我是Java新手,但对编程并不陌生,我在网上搜索了几次,检查了我的代码,一切看起来都很好,在添加用于检查三角数的变量之前,它甚至按预期工作,但在声明变量checkTri和

  • 当我用AES加密和解密字节[128]{1,2,…,126,127}时,一切正常: 解密后将输出字节[128]{1,2,…,126,127}。但当我将raw改为字节[127]{128,129,…,253,254}为相同的加密/解密逻辑时,结果变成字节[381],在[2391189]的循环中: 现在解密后将输出字节[381]{239,191,189,…,239,191,189} 一开始我认为超过127

  • 一、什么是数学? 数学是研究数量、结构、变化以及空间模型等概念的一门科学。 二、数学的特点 数学区别于其他学科的明显特点有三个: 1. 抽象性, 2. 精确性, 3. 应用的极端广泛性。 三、数学的三个传统领域: 1. 研究数的理论的代数学, 2. 研究形的理论的几何学, 3. 沟通形与数且涉及极限运算的分析学, 4. 数学中最重要、最典型的思维方式是演绎,即由基础概念与公理推导出所有的定理。演绎

  • 如果你取一个数字,取它的平方根,去掉小数点,然后把它提高到二次方,结果应该总是小于或等于原来的数字。 这在python中似乎是正确的,直到你出于某种原因在上尝试它。 它看起来像是数学。pow(数学楼层(数学sqrt(99999999999999975425)),2)返回。 我假设这与我们在python中存储值的方式有关...一些与浮点算术相关的东西,但我不能具体解释这是如何影响这种情况的。

  • 我在python中使用的是200位数字。当用数学求一个数的平方根时。我得到了一个错误的答案。 由于x*x(201位)大于n(200位),因此x的值将大于预期值。这里发生了什么?有没有什么概念我弄错了?我怎样才能找到非常大的数的根呢?

  • 公共静态无效字(字符串文本){int numWords=1; 字符串“是this_one_long_word还是几个???你觉得怎么样??太多“应该打印10个字和”!这使用periods.as.word.delimiters,可能很棘手。“应该打印10个单词。 描述如下:一个单词是由一个或多个字符组成的序列,由空格或句子终止符(句号、冒号、分号、问号、感叹号)分隔,无论它是否为实际的英语单词。空白