如果取一个数字,取其平方根,删除小数,然后将其提高到二次幂,结果应始终小于或等于原始数.
这似乎在python中都适用,直到你99999999999999975425
出于某种原因尝试它.
import math
def check(n):
assert math.pow(math.floor(math.sqrt(n)), 2) <= n
check(99999999999999975424) # No exception.
check(99999999999999975425) # Throws AssertionError.
Run Code Online (Sandbox Code Playgroud)
它看起来像math.pow(math.floor(math.sqrt(99999999999999975425)), 2)
回报1e+20
.
我认为这与我们在python中存储值的方式有关...与浮点运算相关的东西,但我不能具体说明这会如何影响这种情况.
Sha*_*ger 21
你的答案非常复杂.问题实际上不是关于sqrt
或者pow
,问题是你使用的数字大于浮点数可以精确表示.标准IEEE 64位浮点运算不能表示超过52位的每个整数值(加上一个符号位).
尝试将输入转换为float
后退:
>>> int(float(99999999999999975424))
99999999999999967232
>>> int(float(99999999999999975425))
99999999999999983616
Run Code Online (Sandbox Code Playgroud)
如您所见,可表示的值跳过16384.第一步math.sqrt
是转换为float
(C double
),此时,您的值增加足以破坏最终结果.
短版:float
无法准确表示大整数.decimal
如果您需要更高的精度,请使用
与Evan Rose(现已删除)的答案声明不同,这不是由于sqrt算法中的epsilon值.
大多数math
模块函数将其输入转换为float
,并且math.sqrt
是其中之一.
99999999999999975425
不能表示为浮点数.对于此输入,强制转换生成一个具有精确数值99999999999999983616的浮点数,其repr
显示为9.999999999999998e+19
:
>>> float(99999999999999975425)
9.999999999999998e+19
>>> int(_)
99999999999999983616L
Run Code Online (Sandbox Code Playgroud)
最接近这个数字的平方根的浮点数就是10000000000.0
,这就是math.sqrt
返回的东西.
归档时间: |
|
查看次数: |
1076 次 |
最近记录: |