上記のために私のために、1:
のPythonの10進数は、文字通り一種でありますあなたが手で書き留めるかもしれない数の重要なのは、再帰の概念を理解していないため、1/3
のような無限に繰り返される部分は、正確さの点までは0.333333333333..
と表されます。これに3を乗算すると、0.99999..
が得られます。これは実際には0.33333333..
が切り捨てられた後に1/3
だったことを実際に知ることができないため、分かりやすい動作です。 Decimal
は、分割するときの丸めによって精度が低下することがよくあります(実際には、2または5以外の因子で割ります)。分割を行うことができることが重要である場合、分子と分母によって、任意の精度の損失なしに、任意の有理数を表すFraction
を使用:
In [1]: from fractions import Fraction
In [2]: Fraction(3) * Fraction(1, 3)
Out[2]: Fraction(1, 1)
In [3]: print(_)
1
画分が自動的に単純化するであろう。
あなたの浮動小数点数では、丸め誤差がキャンセルされたのはちょうど運が良かったと思います。 float
またはDecimal
は、の絶対値がの精度が必要な場合を除き、おそらく十分です(この場合、Fraction
などが推奨されます)。あなたが頻繁になりません実際にはたいした、0.9999999
と1
の違いをシミュレーションのようなものをやっている場合は
In [4]: "{:.2f}".format(Decimal(3) * (Decimal(1)/Decimal(3)))
Out[4]: '1.00'
:あなたは常にそれが少なくとも少しきれいに見えるようにする醜い数締めくくることができます。
もう1つの方法は、分子が分母で割り切れることが保証されるように操作の順序を入れ替えることです。これは Anilkumarの答えです。可能であれば、これは良い解決策ですが、これを行うことができない機会があるかもしれません。例えば、結果が小数であることを期待している場合や、ある種のブラックボックスから分数被乗数を得る場合などです。この時点で、Decimal
分子と分母の両方を追跡することが可能になります。そして、あなたはそれがFraction
のクラスであることを認識しますが、手間は少なくなります。
Fraction
は、Decimal
で実行できるものはすべて重要ですが、より重要なことに使用できます。表現可能な10進数も小数です(10の累乗を超える仮数)。例えば:
In [2]: Fraction("3.141")
Out[2]: Fraction(3141, 1000)
当然のことながら、これはいくつかの失われたパフォーマンスにつながる - 画分は、より多くのデータを追跡する必要があり、より多くの計算を行うと、おそらくやや抽象的です。
有理数を非整数の累乗にすると、結果は合理的でない可能性があるので、途中で分数を失う可能性があることに注意してください。例:
>>> Fraction(1, 2) ** 4
Fraction(1, 16)
>>> Fraction(1, 2) ** 0.5
0.7071067811865476
式を評価する文脈の中では、すべてを記号的に試して保存することはあまり意味がありません。これは、しばしば十分に良いと思われるfloat
という考えに戻ってきます。あなたが本当にsurd出力形式のいくつかの種類を望んでいた場合、あなたはsympy
に打撃を与えることができる:
In [1]: from sympy import *
In [2]: sqrt(Integer(1)/Integer(2))
Out[2]: sqrt(2)/2
をこれはもちろん、さらにあなたを遅くします。
10進数は、分母が3の分数を単純に表すことはできません。有理数についての正確な計算のために、 'fractions'モジュールを見てください。 –
10進数とコンピュータの素晴らしい世界へようこそ。コンピュータで小数を使って複数の計算を行うときの精度の損失を最小限に抑える方法を示すために教えられた数値メソッドのコースがあります。 – LhasaDad
@LhasaDad:私が言ったように、私はずっと複雑な計算をしています。私の質問の例は問題の最小化に過ぎません。実際の計算は 'Decimal(x)*((1 + Decimal(y)/ Decimal(z))**(Decimal(w)/ 1000000) - 1)'であり、目的は実装された式をエミュレートすることです別の(非pythonic)プラットフォーム上で。この目的のために、私はこの計算を精度のために最適化することは許されていません(あるいは、他の方法でそれを変更することはできません)。 – goodvibration