1

整数に近い整数を間違えるコードを避けたいと思います。例えば、58106601358565889はその平方根241,053,109.00000001659385359763188として持っていますが、私は次のブールテストを使用する場合、58106601358565889は、それが完璧な四角だったという考えに私をだまさ:、大きな整数をPythonで近い整数から区別する

a = 58106601358565889 
b = math.sqrt(a) 
print(b == int(b)) 

精度が必ずしも問題ではありませんかの理由はI近く整数対真をテストするためのより良い方法だろう何

print(a == b**2) 

:再チェック、私は適切な(偽)の結論を得ますか? math.sqrtはコード内の別の定義に埋め込まれています。可能であれば、平方根の平方根のチェックを挿入する必要はありません。これは良い質問ではない場合、私はお詫び申し上げます。私はPythonの初心者です。

+0

「true」を返す必要がありますか? – styvane

+0

私の理解が正しい場合は、Falseを返します。 – Backtrack

+0

最初のプリント(b == int(b))falseになりたい。 – Jeptha

答えて

0
import numpy as np 
import math 
from decimal import * 

a = 58106601358565889 
b = np.sqrt(a) 
c = math.sqrt(a) 
d = Decimal(58106601358565889).sqrt() 


print(d) 
print(int(d)) 

print(c) 
print(int(c)) 

print(b) 
print(int(b)) 

O/P

241053109.0000000165938535976 
241053109 
241053109.0 
241053109 
241053109.0 
241053109 

私が使用decimalを言うでしょう。

期待コード:

from decimal import * 
d = Decimal(58106601358565889).sqrt() 
print(d == int(d)) 

O/P

False 
+0

'Decimal'は依然として、(設定可能ですが)精度に限定された計算を行います。 'Decimal'ですべての数学を行うだけで、追加の設定と二次的なチェックを行わない限り、より大きな入力サイズへの問題がただちに延期されます。 – user2357112

+0

ありがとう、Decimalはトリックをしました。私はそのオプションについて知らなかった。 – Jeptha

+0

ありがとうuser2357112、私は 'Decimal'の精度の限界を調べなければなりません。 – Jeptha

0

それが問題であるintの精度ではありません - それは山車

>>> import math 
>>> math.sqrt(58106601358565889) 
241053109.0 
>>> math.sqrt(58106601358565889) - 241053109 
0.0 

の限られた精度だ私は、二重チェックは明白な解決策

+0

だから多分ダブルチェックが本当に必要ですか? – Jeptha

+0

@Jeptha:ダブルチェックでは十分ではありません。それ自体の問題があります。たとえば、 'a = 100000000000000000001 ** 2'で失敗します。 – user2357112

+0

@Jepthaより大きい浮動小数点数は常に整数になります。おそらく '(a == b * b)'をテストするだけです。 –

1

だろう。これは、の問題ではないと思いますbは本当に整数であるため、整数を非整数と区別します。 Pythonの浮動小数点数の精度は、その分数コンポーネントを得るのに十分な数字にaの平方根を表すには不十分です。二つ目は、あなたがやったチェック:bが整数である一方で、b**2はまだaではないので

print(a == b**2) 

Falseを印刷します。

非常に大きな整数が正方形であるかどうかをテストする場合は、平方根アルゴリズムを自分で実装することを検討してください。

*小数部のように、isinstance(b, int)のようにはなりません。

+0

ありがとうございました。それは私の面で悪い仮定だった。 – Jeptha

0

またgmpy2図書館で見ることができます。整数平方根と整数平方根+剰余を計算する関数を持っています。精度の制約はありません。

>>> import gmpy2 
>>> gmpy2.isqrt(58106601358565889) 
mpz(241053109) 
>>> gmpy2.isqrt_rem(58106601358565889) 
(mpz(241053109), mpz(8)) 
>>> 

免責事項:私はgmpy2を維持しています。

関連する問題