Python:如何保持 sqrt() 平方的准确性?

ddy*_*yke -1 python

我认为这是一个受欢迎的问题,但我找不到答案:

当一个整数的平方根被平方时,我希望结果是一个整数,但我得到以下结果:

from math import sqrt
from decimal import Decimal 

a = 5
b = sqrt(Decimal(a))
c = 2 * b ** 2
print(a, c)
if c.is_integer():
    print('c is integer')
    do something ...
else:
    print('c is NOT integer')
Run Code Online (Sandbox Code Playgroud)

结果:

5 10.000000000000002
c is NOT integer
Run Code Online (Sandbox Code Playgroud)

我也试过不使用 decimal.Decimal() 但它也不起作用。解决这个问题的最佳方法是什么?上面的代码针对这个问题进行了简化,但如果可能的话,我想要一个通用的解决方案。我正在使用 Python 3.5。

Pau*_*zer 5

如果您想要“准确”的表示,sqrt(5)您必须熟悉 CAS 或计算机代数系统,例如 sympy。

>>> import sympy
>>> s = sympy.sqrt(5)
>>> s
sqrt(5)
>>> s*s
5
>>> type(s*s)
<class 'sympy.core.numbers.Integer'>
>>> float(s)
2.23606797749979
Run Code Online (Sandbox Code Playgroud)

sqrt(5) 是所谓的无理数。这意味着它不能写成分数。使用他们的普通算术计算机只能存储分数,甚至不能存储全部,所以在这条路上你很不走运。

这是您的代码段到 sympy 的翻译,演示了该功能simplify

import sympy

def check_int(x, name='input'):
    print('ah', name, '=', x)
    sx = sympy.simplify(x)
    if sx != x:
        print('let me think...')
        print("that's", sx)
    if isinstance(sx, (int, sympy.Integer)):
        print(name, 'is integer')
    else:
        print(name, 'is NOT integer')
    print()

s = sympy.sqrt(5)
t = sympy.sqrt(3)
check_int(5)
check_int(s)
check_int(s**2)
check_int((s+1)**2)
check_int((s+1)**2-2*s)
check_int((s-t)**2)
Run Code Online (Sandbox Code Playgroud)

输出:

ah input = 5
input is integer

ah input = sqrt(5)
input is NOT integer

ah input = 5
input is integer

ah input = (1 + sqrt(5))**2
input is NOT integer

ah input = -2*sqrt(5) + (1 + sqrt(5))**2
let me think...
that's 6
input is integer

ah input = (-sqrt(3) + sqrt(5))**2
let me think...
that's -2*sqrt(15) + 8
input is NOT integer
Run Code Online (Sandbox Code Playgroud)