Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.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 四舍五入**0.5和math.sqrt_Python_Math_Square Root - Fatal编程技术网

Python 四舍五入**0.5和math.sqrt

Python 四舍五入**0.5和math.sqrt,python,math,square-root,Python,Math,Square Root,在Python中,是 n**0.5 # or math.sqrt(n) 当一个数字是一个完美的正方形时能被识别吗?具体来说,当我使用 int(n**0.5) # instead of int(n**0.5 + 0.000000001) 由于精度错误,我可能会意外地得到小于实际平方根的数字1。使用浮点运算执行计算。在计算平方根之前,将输入转换为浮点 这些计算是否能识别输入值何时为完美正方形 不,他们没有。浮点运算没有完美平方的概念 对于数字的有效位数大于浮点尾数的值,大整数可能无法表示。

在Python中,是

n**0.5  # or
math.sqrt(n) 
当一个数字是一个完美的正方形时能被识别吗?具体来说,当我使用

int(n**0.5)  # instead of
int(n**0.5 + 0.000000001)

由于精度错误,我可能会意外地得到小于实际平方根的数字1。

使用浮点运算执行计算。在计算平方根之前,将输入转换为浮点

这些计算是否能识别输入值何时为完美正方形

不,他们没有。浮点运算没有完美平方的概念

对于数字的有效位数大于浮点尾数的值,大整数可能无法表示。因此,很容易看出,对于不可表示的输入值,
n**0.5
可能不准确。而您提出的通过添加一个小值来修复的方法通常不会解决问题

如果输入是整数,则应该考虑使用整数运算进行计算。这最终是解决这个问题的正确方法。

是的,你应该担心:

In [11]: int((100000000000000000000000000000000000**2) ** 0.5)
Out[11]: 99999999999999996863366107917975552L

In [12]: int(math.sqrt(100000000000000000000000000000000000**2))
Out[12]: 99999999999999996863366107917975552L
显然,在这里添加
0.00000001
也没有帮助

正如@DSM指出的,您可以使用该库:

对于超过
10**99999999的数字,如果您检查精度(可配置),它将抛出一个错误而不是一个错误的答案…

您可以在转换为int之前使用舍入(数字,有效数字),我记不起在进行浮点到整数转换时python是否使用trunc或rounds

在任何情况下,由于python使用浮点运算,所有的陷阱都适用。请参阅:

完美的平方值没有分数分量,因此您主要担心的是非常大的值,对于这样的值,1或2的差异非常大,这意味着您需要一个支持如此高精度的特定数字库(正如DSM所提到的,
Decimal
库是Python 2.4以来的标准库,它支持任意精度,因此应该能够做您想要做的事情


由于一些答案建议使用整数算术,我推荐使用该库。它提供了检查数字是否为完美幂、计算整数平方根和带余数的整数平方根的函数

>>> import gmpy2
>>> gmpy2.is_power(9)
True
>>> gmpy2.is_power(10)
False
>>> gmpy2.isqrt(10)
mpz(3)
>>> gmpy2.isqrt_rem(10)
(mpz(3), mpz(1))

免责声明:我维护gmpy2。

sqrt
是更容易实现的数学库函数之一,任何质量合理的数学库都将以忠实的舍入(亚ULP精度)实现它。如果输入是一个完美的平方,则其平方根是可表示的(以合理的浮点格式).在这种情况下,忠实的四舍五入保证了结果的准确性


这只处理实际传递给
sqrt
的值。一个数字是否可以从另一种格式无误地转换为
sqrt
的浮点输入是一个单独的问题。

将结果四舍五入到
float
的精度是导致问题的原因,而不是
sqrt自身。避免它的唯一方法是使用整数平方根函数。
>>'%0.0f'%float(1000000000000000000000000000)“9999999999999996863366107917975552”
请注意,在使用
十进制时,您仍然必须确保精度足够——这使得获得正确答案成为可能,而不是自动的。您得到的是荒谬的数字,因为您平方然后平方根的东西实际上不是1036,而是最接近的e> 加倍。@tmyklebu是的……因此值得担心。@AndyHayden:我的观点是,这是一个表示问题,而不是一个算术问题。+1。
Decimal('100000000000000000000000000000000000000000000')。sqrt()Decimal('1.000000000000000000000E+35'))
你有没有一个不涉及次正常、下溢或上溢的反例?@tmyklebu什么反例。我要说的是编码是否能检测到完美的正方形。这不是因为它使用的是浮点运算,它没有完美的正方形的概念。问题的第一句是关于识别。第二句是ks关于得到错误答案的问题。所以关于反例的问题是,如果
sqrt
不返回精确的平方根,是否可以显示一个完美的平方值。@eric这很容易显示。您所需要的只是一个不可表示的数。@tmyklebu忘记次正常值和上溢/下溢永远不要讨论这个问题。我的意思是,对于整数n,n**0.5不是溢出就是下溢。你所需要的只是一个不可表示的数字。我想你可以说得更有力一些,也就是说,对于合理的指数,
sqrt(x*x)==x
,因为
(x+ulp/2)*(x+ulp/2)
,即
sqrt
开始给出错误值的地方,总是比ulp高出一个ulp,
(x-ulp/2)*(x-ulp/2)
比ulp小,除非
x
在2的幂的几ulp之内。@tmyklebu:这似乎是使用正确舍入的参数(错误最多为1/2 ulp)。忠实舍入最多允许一个ULP(独占)。任何时候,如果结果不可精确表示,可能会返回两个值。因此,除非
x*x
精确,否则您无法保证
sqrt(x*x)=x
。IEEE不保证正确舍入
sqrt
?(我知道Python可能没有理由在意IEEE所说的话。但我从未见过数学库出错,因此,出于实际目的,我觉得依靠正确舍入的
sqrt
,并根据正确舍入的
sqrt
提出建议是可以的。我认为我的论点可能也适用于fait。)h完全四舍五入的
sqrt
,但有更多的边缘情况,尤其是
sqrt(2)
,需要特别注意。)@
>>> import gmpy2
>>> gmpy2.is_power(9)
True
>>> gmpy2.is_power(10)
False
>>> gmpy2.isqrt(10)
mpz(3)
>>> gmpy2.isqrt_rem(10)
(mpz(3), mpz(1))