asでの計算精度

詳説AS3.0 P216のあたり
多次元配列の説明の例を実際にやってみた

var row1:Array = [6, 2.99];
var row2:Array = [4, 9.99];
var row3:Array = [1, 59.99];
var spreadsheet:Array = [row1, row2, row3];
var total:Number;
for(var i:int = 0; i < spreadsheet.length; i++){
total += spreadsheet[i][0]*spreadsheet[i][1];
}
trace("total:" + total);

としたら

total:NaN

…?
原因切り分けのため 個別に計算して全部足してみた。

var total1:Number;
var total2:Number;
var total3:Number;
total1 = spreadsheet[0][0] * spreadsheet[0][1];
total2 = spreadsheet[1][0] * spreadsheet[1][1];
total3 = spreadsheet[2][0] * spreadsheet[2][1];
total = total1 + total2 + total3;

としたら

total:117.89000000000001
total1:17.94
total2:39.96
total3:39.96

なのに 全部足すと

117.89000000000001

…?
どこか間違っているのだろうか?元々精度がこんなものなのか?

asでの計算精度」への4件のフィードバック

  1. いしはら

    このブログ スクリプト書くには 向いていないな
    あとでcss書き足したい

  2. yebi

    小数は普通は浮動小数点なので、2進に変換して有限小数にならない場合は誤差が出る可能性があります。
    当該の計算をCで書いてみたところ、僕の環境ではdoubleでは117.890000ですが、floatでは117.889999になりました。
    また、上の計算でNaNになっているのは初期化していないtotalを+=しているからかもしれません。

  3. いしはら

    >yebiさん
    コメントありがとうございます。
    ご指摘の通り totalを初期化したらNaNでなく 
    total:117.89000000000001
    と(この場合の)正しい値を得ることができました。
    小数点第14位の値は 誤差…なんですね。
    そういう場合があるのと
    プログラムの作法に不慣れなのですが
    厳密な値がいらない場合は 
    切り捨てなり丸めるなりする
    とよいのかなと 理解しました。
    ありがとうございました

  4. serif blog

    記念キャプチャ

    以前のエントリにコメントをもらっていたことに気づいて 内容を…

コメントは停止中です。