我需要计算一些数字的平方根,例如√9 = 3
和√2 = 1.4142
,如何在Python中实现?
输入可能都是正整数,而且相对较小(比如小于10亿),但万一不是这样,有什么可能会出错吗?
- 相关**
- Integer square root in python
- How to find integer nth roots?
- Is there a short-hand for nth root of x in Python?
- Difference between **(1/2), math.sqrt and cmath.sqrt?
- Why is math.sqrt() incorrect for large numbers?
- Python sqrt limit for very large numbers?
- Which is faster in Python: x**.5 or math.sqrt(x)?
- Why does Python give the "wrong" answer for square root?(特定于Python 2)
- calculating n-th roots using Python 3's decimal module
- How can I take the square root of -1 using python?(聚焦于NumPy)
- Arbitrary precision of square roots
注意:这是在a discussion on Meta之后大约an existing question with the same title处尝试canonical question。
9条答案
按热度按时间3phpmpom1#
选项1:第一个月
标准库中的
math
模块有一个sqrt
函数来计算一个数的平方根,它接受can be converted tofloat
(包括int
)作为参数,并返回一个float
。选项2:分数指数
幂运算符(
**
)或内置的pow()
函数也可以用来计算平方根。幂运算符需要数值类型,并且与二进制算术运算符的转换规则匹配,因此在这种情况下,它将返回
float
或complex
数字。(Note:在Python 2中,
1/2
被截断为0
,所以你必须用1.0/2
或类似的来强制浮点运算。这种方法可以推广到nth root,尽管不能精确表示为
float
的分数(如1/3或任何不是2的幂的分母)可能会导致一些不准确:边缘案例
阴性和复杂
指数运算适用于负数和复数,尽管结果有一些轻微的误差:
注意
-25
上的括号!否则它会被解析为-(25**.5)
,因为求幂比一元求反更紧密地绑定。同时,
math
只为浮点数构建,所以对于x<0
,math.sqrt(x)
将使ValueError: math domain error
自乘,对于复数x
,它将使TypeError: can't convert complex to float
自乘,相反,您可以使用cmath.sqrt(x)
,它比求幂更精确(也可能更快):精密度
这两个选项都涉及到到
float
的隐式转换,因此floating point precision is a factor。例如:非常大的数字甚至可能不适合一个浮点数,你会得到
OverflowError: int too large to convert to float
。其他类型
让我们以
Decimal
为例:除非指数也是
Decimal
,否则求幂失败:同时,
math
和cmath
会将它们的参数分别静默地转换为float
和complex
,这可能意味着精度损失。decimal
也有自己的.sqrt()
。另请参见calculating n-th roots using Python 3's decimal moduleyr9zkbsy2#
象征
根据您的目标,尽可能长时间地延迟平方根的计算可能是一个好主意。SymPy可能会有所帮助。
SymPy是一个用于符号数学的Python库。
一开始看起来没什么用。
但sympy可以给予比浮点数或Decimal更多的信息:
同样,精度也不会丢失。(√2)²仍然是整数:
相比之下,float和Decimals将返回非常接近2但不等于2的数字:
Symy还可以理解更复杂的示例,如the Gaussian integral:
最后,如果需要十进制表示法,可以要求比实际需要更多的位数:
ryevplcw3#
编号
docs
阴性
对于负实数,它将返回
nan
,因此np.emath.sqrt()
在这种情况下可用。当然,另一种选择是先转换为复数:
jmo0nnb34#
牛顿法
计算平方根最简单和最精确的方法是牛顿法。
你有一个数字,你想计算它的平方根(
num
),你有一个猜测的平方根(estimate
)。估计可以是任何大于0的数字,但一个有意义的数字会大大缩短递归调用的深度。这一行使用这两个参数计算更精确的估计值。您可以将
new_estimate
值传递给函数并计算另一个new_estimate
,它比前一个更精确,或者您可以像这样定义递归函数。例如,我们需要求30的平方根,我们知道结果在5和6之间。
数字为30,估计值为5。每个递归调用的结果为:
最后一个结果是number的平方根的最精确计算,它与内置函数
math.sqrt()
的值相同。vuv7lop35#
Python的
fractions
模块和它的类Fraction
实现了有理数的算术运算。Fraction
类没有实现平方根运算,因为大多数平方根都是无理数。但是,它可以用来近似任意精度的平方根,因为Fraction
的分子和分母都是任意精度的整数。下面的方法采用正数
x
和迭代次数,并返回x
平方根的上界和下界。有关此操作实现的详细信息,请参阅下面的参考,它还显示了如何实现其他具有上界和下界的操作(尽管
log
操作显然至少有一个错误)。或者,使用Python的
math.isqrt
,我们可以计算任意精度的平方根:i
的平方根在正确值的1/2 * n * 范围内,其中i
是整数:x1米10英寸1x.i
的平方根在正确值的1/10 * n * 范围内,其中i
是整数:Fraction(math.isqrt(i * 10**(n*2)), 10**n)
的数据。x
的平方根在正确值的1/2 * n * 范围内,其中x
是1/2 * n * 的倍数:Fraction(math.isqrt(x * 2**(n)), 2**n)
.x
的平方根在正确值的1/10 * n * 范围内,其中x
是1/10 * n * 的倍数:Fraction(math.isqrt(x * 10**(n)), 10**n)
.在上述中,
i
或x
必须是0或更大。hgtggwj06#
二进制搜索
好处:
我个人为一个加密CTF挑战(RSA立方根攻击)实现了这个,在这个挑战中我需要一个精确的整数值。
一般的想法可以延伸到任何其他的根源。
编辑:
正如@wjandrea所指出的,这个示例代码不能计算。这是它没有将任何内容转换为浮点数的副作用,因此不会丢失精度。如果根是整数,则将其返回。如果不是,你会得到平方小于你的数的最大数。我更新了代码,这样它也会返回一个bool来指示值是否正确,并且修正了一个导致无限循环的问题(@wjandrea也指出了这一点)。这种通用方法的实现对于较小的数字仍然工作得有点奇怪,但超过10我就没有问题了。
克服此方法/实现的问题和限制:
对于较小的数字,你可以使用其他答案中的所有方法。他们通常使用浮点数,这 * 可能 * 会损失精度,但对于小整数,这应该意味着没有任何问题。所有使用浮点数的方法都有相同(或几乎相同)的限制。
如果你仍然想使用这个方法并得到浮点结果,那么把它转换成使用浮点也是很容易的。注意,这将重新引入精度损失,这是这个方法相对于其他方法的独特优点,在这种情况下,你也可以只使用任何其他的答案。我认为牛顿方法的版本收敛得更快一些,但我不确定。
对于较大的数字,浮点数会损失精度,这个方法可以给出更接近实际结果的结果(取决于输入的大小)。如果你想处理这个范围内的非整数,你可以使用其他类型,例如固定精度的数字。
编辑2,关于其他答案:
目前,afaik,唯一的其他答案,有类似或更好的精度为大数比这个实现是一个建议SymPy,由埃里克Duminil。该版本也更容易使用,并为任何类型的数字工作,唯一的缺点是,它需要SymPy。我的实现是免费的任何巨大的依赖性,如果这是你正在寻找的。
8ehkhllq7#
任意精度平方根
这个变体使用字符串操作将表示十进制浮点数的字符串转换为
int
,调用math.isqrt
来执行实际的平方根提取,然后将结果格式化为十进制字符串。math.isqrt
向下舍入,因此所有生成的数字都是正确的。输入字符串
num
必须使用纯浮点格式:不支持“e”表示法。num
字符串可以是纯整数,并且忽略前导零。digits
参数指定结果字符串中的小数位数,即小数点后的位数。测试
输出
对于小数位数,使用
decimal.Decimal.sqrt
会更快一些,大约32位数时,str_sqrt
的速度与Decimal.sqrt
大致相同,但对于128位数时,str_sqrt
比Decimal.sqrt
快2.2倍,对于512位数时,str_sqrt
比Decimal.sqrt
快4.3倍,对于8192位数时,str_sqrt
比Decimal.sqrt
快7.4倍。这是一个运行在SageMathCell服务器上的live version。
yyhrrdl88#
在python3中,你可以用下面的代码计算任意精度的平方根:
文档链接:https://pypi.org/project/num7/https://github.com/giocip/num7
knsnq2tg9#
求一个数的平方根
输出:-
输入一个数字:24
24的平方根==〉4.898979485566356
输入一个数字:36
36的平方根==〉6
输入一个数字:49
49的平方根==〉7
✔💡点击下面的输出并查看✔