演算結果が半端な値になる(丸め誤差) [Edit]

Flashのバグ?
以下のステートメントを実行してみましょう。0.01ではなく、0.00099999999999989というような半端な値が返ります。

trace (1.001-1);

JavaScriptでも、演算結果には同様の誤差が生じます。つまり、これはFlashのバグではなく、仕様ですこういうものだと思って、諦めましょう。

というのでは、あまりに素っ気ないので、もう少し解説を加えます(でも、結論としては、仕様というしかありません)。

丸め誤差
これは、いわゆる「丸め誤差」(round-off error)といわれるものです。コンピュータは、数値の演算を有限の桁数で行います。そのため、有効桁数未満の桁は四捨五入されます。そこで誤差が発生することになるのです。人間の目からは、1.001-1で誤差の生じる余地はなさそうに見えます。けれど、コンピュータは2進数で計算を行っていることに注意が必要です。

1.001と1では、その差がごく僅かです。このような浮動小数の引き算では、有効桁数が減少する「桁落ち」という誤差の生じることがあるのです。さらに興味のあるマニアックな方は、「丸め誤差」をキーワードにネット検索されることをお勧めします。


[追記2011/08/25]
「ActionScript 2.0リファレンスガイド」の「%剰余演算子」のページは、つぎのような誤差が生じる例を挙げています。

trace(4.3%2.1); // traces 0.0999999999999996

そして、つぎのように説明します。この例の「 traceステートメントでは0.1ではなく、0.0999999999999996が返されます。これは2進数計算では浮動小数点の精度に限度があるからです」。

また、AdobeのFlash PlayerエンジニアTinic Uro氏は、kaourantin.netの記事「New Flash Player beta version」のコメントで、「IEEE 754(IEEE 浮動小数点数演算標準)」にもとづく言語はすべて同じような結果になると説明しています。

コメント

この記事へのコメント

  1. 1.attun(2004年04月24日 00:00)

    ぼくもあきらめました。
    というよりも
    0.0001をたして数値を作り直すようなことをしました。

  2. 2.fastest(2008年03月14日 12:09)

    有効桁数を考慮しないでまとめるのはおかしいです。
    例えば電卓ではちゃんと結果が出ます。

    普通にFlashでも避ける方法はあるわけで
    そろそろ修正していただきたい記事です。

  3. 3.野中 文雄(2008年03月16日 05:05)

    電卓は10ないし12桁の表示です。その桁数に「四捨五入」すれば、同じ「結果」が返ります。その意味でしたら、「避ける方法」は、示してあるつもりです。どのような「修正」をお望みでしょうか?

    var nResult:Number = 1.001-1;
    trace(nResult); // 出力: 0.0009999999999998899
    var n12:Number = Math.pow(10, 12);
    trace(Math.round(nResult*n12)/n12); // 出力: 0.001

この記事にコメントを書く

記事に対するテクニカルな質問はご遠慮ください(利用規約)。

その他の記事