3

重複の可能性: python
- floats の小数点以下の問題

以下のコードにpercentageは、float である変数があります。numberifが に達した場合10,000、がだけ上がるように設定しpercentageました.01

# Tries to find a number that when squared and 5%'ed is still a square.

import math

print("Script has started:\n")

percentage = .1
number = 1
while number != -1:
    number = number + 1
    num_powered = number ** 2
    num_5per = num_powered * percentage
    num_5per_sqrt = math.sqrt(num_5per)
    num_list = list(str(num_5per_sqrt))
    dot_location = num_list.index(".")
    not_zero = 0
    for x in num_list[dot_location + 1:]:
        if x != "0":
            not_zero = 1
            break
    if not_zero == 0:
        print("*********************************")
        print("Map :",number)
        print("Safe-Area :",num_5per_sqrt)
        print("Percentage :",percentage)
        print("*********************************")
        input()

    if number > 10000:
              number = 0
              percentage = percentage + .01
              print(percentage)

出力:

0.11
0.12
0.13
0.14
0.15000000000000002  # Here is where it goes crazy
0.16000000000000003
4

4 に答える 4

16

Python ドキュメントから

これは 2 進浮動小数点の性質そのものであることに注意してください。これはPython のバグではなく、コードのバグでもありません(強調は私のものです)。ハードウェアの浮動小数点演算をサポートするすべての言語で、同じ種類のものが表示されます (一部の言語では、デフォルトで、またはすべての出力モードで違いが表示されない場合があります)。

おそらくモジュールを使用するdecimal必要があります。

于 2012-08-08T21:01:50.617 に答える
6

浮動小数点数を使用していて、表現エラーが発生しました。特に、0.01 には 2 進浮動小数点数としての正確な表現がありません。代わりに、0.01 に非常に近いが正確には等しくない数値が格納されます。これはバグではありません。これは、浮動小数点演算が機能する方法です。

いくつかの方法で問題を解決できます。

  • 結果が完全に正確ではないことを受け入れるか、
  • すべてに 100 を掛けて、整数を操作するか、
  • Decimalタイプを使用してください。

例:

from decimal import Decimal
percentage = Decimal('0.1')
step = Decimal('0.01')
percentage += step
于 2012-08-08T20:59:57.453 に答える
1

float には無限の精度がないため、このような奇妙な動作が発生します。

より良い解決策は、パーセンテージを 10 分の 1 のパーセントを表し、1 ずつ増加する整数として保存することです。

例えば:

percent_as_integer += 1

それ以外の

percent_as_float += 0.01

パーセンテージを表示するには、次のようにします。

print "%d.%02d" % divmod(percent_as_integer, 100)

編集:実際には、別の回答で提案されているように、代わりに decimal モジュールを使用することは、おそらくより優れた、より Pythonic なソリューションです。

于 2012-08-08T21:00:46.003 に答える
1

他の回答で説明されているように、これは現在のすべてのマイクロプロセッサにおけるネイティブ浮動小数点数の制限です。

10 進数の正確な表現が必要な場合 (会計やビジネス アプリケーションなど)、浮動小数点ではなく 10 進数を使用する必要があります。decimal 型の高性能な実装であるcdecimalモジュールを使用することもできます。

更新: Python v3.3 以降では、組み込みの decimal モジュールが C で実装されています。

于 2012-08-08T21:10:21.413 に答える