9

私は最近Haskellチュートリアルを行ってきましたが、インタラクティブghciシェルでいくつかの単純なHaskell式を試したときにこの動作に気づきました。

Prelude> 1.1 + 1.1 == 2.2
True
Prelude> 1.1 + 1.1 + 1.1 == 3.3
False
Prelude> 1.1 + 1.1 + 1.1 > 3.3
True
Prelude> 1.1 + 1.1 + 1.1
3.3000000000000003

誰かがそれがなぜであるか知っていますか?

4

7 に答える 7

37

1.13.3浮動小数点数だからです。.1や.3などの小数は、2進浮動小数点数で正確に表すことはできません。.1は1/10を意味します。これを2進数で表すには、各小数桁が1/2 n(1 / 2、1 / 4、1 / 8など)を表す場合、無限の桁数0.000110011...を無限に繰り返す必要があります。

これは、たとえば基数10で1/3を表すのとまったく同じ問題です。基数10では、1/3を正確に表すには、無限の桁数.33333...が必要になります。したがって、基数10で作業する場合、通常は.33のように丸めます。しかし、そのコピーを3つ合計すると、1ではなく.99になります。

このトピックの詳細については、すべてのコンピューター科学者が浮動小数点演算について知っておくべきことを参照してください。

Haskellで有理数をより正確に表すために、いつでも有理データ型を使用できますRatio。分子と分母の型としてbignum(IntegerHaskellでは任意に大きい整数、Int固定サイズではありません)と組み合わせると、任意精度の有理数を表すことができますが、浮動小数点数よりも大幅に低速です。ハードウェアであり、速度が最適化されています。

浮動小数点数は、科学的および数値計算の最適化であり、精度と高速性をトレードオフし、丸めとそれが計算に与える影響を認識している限り、非常に多くの計算を短時間で実行できるようにします。 。

于 2010-01-10T21:22:55.753 に答える
14

浮動小数点数が正確ではないため (ウィキペディア)

于 2010-01-10T21:17:30.117 に答える
13

有理型を使用して、Haskellの浮動小数点エラーを回避できます。

Prelude Data.Ratio> let a = (11 % 10) + (11 % 10) + (11 % 10)
Prelude Data.Ratio> a > (33 % 10)
False
Prelude Data.Ratio> fromRational a
3.3

もちろん、精度を上げるとパフォーマンスが低下します。

于 2010-01-10T21:34:16.833 に答える
6

これは、IEEE浮動小数点数の動作方法と関係があります。

1.1は浮動小数点で1.1000000000000001として表され、3.3は3.2999999999999998として表されます。

つまり、1.1 + 1.1+1.1は実際には

1.1000000000000001 + 1.1000000000000001 + 1.1000000000000001 = 3.3000000000000003

ご覧のとおり、これは実際には3.2999999999999998よりも大きくなっています。

通常の回避策は、同等性を評価しないか、数値がターゲット+/-小さなイプシロン(必要な精度を定義する)内にあるかどうかを確認することです。

例:両方が真の場合、合計は3.3に「等しい」(許容誤差内)。

1.1 + 1.1 + 1.1 < 3.3 + 1e9 
1.1 + 1.1 + 1.1 > 3.3 - 1e9
于 2010-01-10T21:23:49.557 に答える
6

典型的な浮動小数点エラーの問題のように見えます。

浮動小数点/丸め誤差の簡単な例は何ですか?を参照してください。

于 2010-01-10T21:16:58.957 に答える
5

IEEE 754表現を使用して正確に表現できるフロートはほとんどないため、常に少しずれています。

于 2010-01-10T21:17:12.163 に答える
1

一般に、フロートを同等と比較するべきではありません(上記の理由により)。私が考えることができる唯一の理由は、「この値は変更されましたか?」と言いたい場合です。たとえば、「if(newscore / = oldscore)」の場合、何らかのアクションを実行します。2つの別々の計算の結果を比較して、それらが等しいかどうかを確認しない限り、これは問題ありません(数学的にも等しい場合でも、そうでない場合は丸められる可能性があるため)。

于 2010-06-17T00:58:51.583 に答える