2

ほとんどのプログラミング言語で浮動小数点が 100% 正確ではないことは承知していますが、奇妙な問題に遭遇しました。私はまだ Python を学んでいるので、可能な限り少ない量のコインで与えられた釣り銭を計算する簡単なプログラムを作成しました。しかし、0.02 になると、2 ペンス コインの発行に失敗したように見え、代わりに 2 枚の 1 ペンス コインに分割されます。コード スニペットは次のようになります。

....
elif amountLeft / 0.02 >= 1:
    changeGiven.append("2p")
    amountLeft -= 0.02
else:
    changeGiven.append("1p")
    amountLeft -= 0.01

私はhttp://www.pythontutor.comでそれを見てきましたが、それまでに削減されるものの最終的な反復には明らか0.02にあります。amountLeft確認すると、期待どおりprint 0.02 / 0.02 >= 1に戻りTrueます。

ここで私が見逃している明らかなことは何ですか?

4

3 に答える 3

3

まず第一に、( が負でないことを前提amountLeft / 0.02 >= 1として) とほとんど同じで、少し単純です。amountLeft >= 0.02amountLeft

整数演算を使用する (ペニーを直接操作すると、正確な結果が得られますが、.結果を表示するときに手動で追加する必要があります。

from Decimal import decimal

amountLeft = round(amountLeft*100)

....
elif amountLeft >= 2:
    changeGiven.append("2p")
    amountLeft -= 2
else:
    changeGiven.append("1p")
    amountLeft -= 1

10 進数を正確に処理するプログラムが本当に必要な場合は、decimal モジュールを使用してください。入力が浮動小数点であると仮定します。

# Assume amountLeft contains a floating point number (e.g. 1.99)
# 2 is the number of decimals you need, the more, the slower. Should be 
# at most 15, which is the machine precision of Python floating point.

amountLeft = round(Decimal(amountLeft),2)  

....
# Quotes are important; else, you'll preserve the same errors 
# produced by the floating point representation.
elif amountLeft >= Decimal("0.02"):
    changeGiven.append("2p")
    amountLeft -= Decimal("0.02")
else:
    changeGiven.append("1p")
    amountLeft -= Decimal("0.01")
于 2013-05-29T16:07:50.700 に答える
-4

浮動小数点へようこそ。0.02 / 0.02 は必ずしも 1 に等しいとは限りません。私の最善の推奨事項は、すべてに対して常に整数演算を使用することです。私は一日中科学的プログラミングを行っていますが、浮動小数点が必要な問題はまだ見つかっていません。わかりやすくするためにもう一度言います。浮動小数点演算で解決できると思われる問題はすべて、整数演算でより効果的に解決できます。私が考えることができる唯一の例外は、浮動小数点入力のみを受け入れるライブラリを使用する必要がある場合です。

浮動小数点の使用を主張する場合は、丸め関数を使用する必要があります。

--------------------- または FJ が提案する 10 進ライブラリ。

于 2013-05-29T15:55:49.820 に答える