Pythonでdouble/float / etcの有効数字を数える方法はありますか?これを行う簡単な方法はわかりませんが、ライブラリにあると思います。
前もって感謝します。
Pythonでdouble/float / etcの有効数字を数える方法はありますか?これを行う簡単な方法はわかりませんが、ライブラリにあると思います。
前もって感謝します。
いいえ。有効数字はそれほど大きな問題ではなく、コンピューター言語ではほとんどサポートされていません。実際の計算を行う人は、はるかに精度の高いエラーバーを必要とします。実際の測定では、「これは0.1mmです」または「これは0.11mmです」というあまり正確ではないステートメントではなく、「これは0.11±0.03mmです」などの非常に正確なことを言います。 」は、不正確さが実際には10の累乗に落ちない場合でも、10の累乗を選択するようにします。
次のような任意精度の浮動小数点ライブラリに興味があるかもしれません。
私は別の質問でこの投稿の解決策を見つけました:
ここでの考え方は、floatを文字列としてメソッドに渡し、メソッドが正規表現を使用して、文字列を分割することによって有効桁数をカウントすることです。ここで、"e"
は(科学的形式のfloat文字列の場合)、ドットは(通常の浮動小数点文字列)。
有効数字8桁まではうまく機能するようですが、9桁目以降の動作は保証されません。
それでも、これは
「有効数字はそれほど大したことではなく、コンピューター言語ではほとんどサポートされていません」
応答。簡単ではないかもしれませんが、完全ではないにしても、間違いなくそれを行うことができます。
コンピュータは、少なくとも、そうするようにプログラムされていない限り、そのようには機能しません。仮定はあなたがそれらに与える数が正確であるということです。数値2/3を0.6666666666666667として作成すると、すべての操作でそれが正確に処理されます。最下位桁のエラーは、後の計算でより大きなエラーに伝播する可能性がありますが、これは、可能な場合にこれらの問題を最小限に抑えるアルゴリズムを使用して、優れたコードで処理する必要があります。
しかし、私が言ったように、コンピューターは彼らがするように言われたことをします。したがって、区間演算と呼ばれるものを使用するように記述されたパッケージがあります。その場合、数値は間隔として記述される可能性があるため、間隔[0.6666666666666666,0.6666666666666667]として2/3を作成する場合があります。間隔、加算、減算、乗算などを操作できます。これらの操作では、操作するにつれて間隔の幅が広がることがよくあります。
ただし、実際には、区間演算ツールを使用する場合でも、数値の有効桁数を最初に知っておく必要があるのはあなたです。2.2として数値を作成し、それをdoubleとして格納すると、コンピュータは実際に数値を2.200000000000000として格納しようとし、すべての桁が正確に正しいと見なします。もちろん、浮動小数点演算が採用されているため、数値は実際には2進数として内部に格納されます。したがって、2.2はおそらく数値として効果的に保存されます。
2.20000000000000017763568394002504646778106689453125
ほとんどの小数はバイナリ形式で正確に表現できないためです。繰り返しになりますが、すべてのソフトウェアで注意を払う必要がありますが、それらのツールを使用している人は、その数が実際に何を意味するのかを理解するために常に注意を払う必要があります。
この最後の点は重要です。多くの人々は、コンピューターによって生成された数字を、コンピューターの神が石のタブレットに伝えたように、真実として扱います。コンピューターが1.4523656535725を印刷する場合、彼らは自分が見ているもののすべての桁を信じています。実際、ここでは常識を適用する必要があります。おそらく、この数値は有効数字3桁のデータから生成されたものであるため、その数値の最初の数桁のみに依存することを選択できます。そしてもちろん、これがあなたが学校でその概念について教えられ、何を信頼し、何を信頼しないかを知る理由です。ただし、覚えておいてください。コンピュータは通常、無限に信頼します。フィルタを適用する必要があるのはあなたです。
組み込みのDecimalライブラリは、ハードウェアベースの浮動小数点数の使用に関する懸念を回避するため、これに非常に役立ちます。有効数字と指数のみを含む内部表現があります。したがって、これを使用して、次のような有効数字を数えることができます。
from decimal import Decimal
def count_sigfigs(numstr):
return len(Decimal(numstr).normalize().as_tuple().digits)
これは、(この関連する質問からの)これらの例のような多くの例で非常にうまく機能します。正しく機能させるには、数字を文字列として入力する必要があることに注意してください。フロートを使用すると、ハードウェア表現のために混乱します。
tests = [('2', 1),
('1234', 4),
('2.34', 3),
('3000', 1),
('0.0034', 2),
('120.5e50', 4),
('1120.5e+50', 5),
('120.52e-50', 5)]
for num, expected in tests:
print(count_sigfigs(num) == expected)
これは次のようになります。
True
True
True
True
True
True
True
True
残念ながら、これは4つの有効数字を持つ「1.000」のような数値では完全には機能しません。これは1になります。したがって、すべてのケースをカバーするには改善が必要です。また、「0」には1が与えられますが、通常は0になります。
あなたがそれを取り出すならば、normalize
それは3000のために働きます1.000
が、そうではありません(それは1ではなく4を言います)。