C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: JavaScriptの小数計算の誤差


(過去ログ 87 を表示中)

[トピック内 3 記事 (1 - 3 表示)]  << 0 >>

■51825 / inTopicNo.1)  JavaScriptの少数計算の誤差
  
□投稿者/ まっち (4回)-(2010/07/21(Wed) 17:29:20)

分類:[JavaScript] 

JavaScriptの計算で質問させて頂きます。
小数点以下二位で四捨五入をする必要があります。

var a = 74;
var b = 95;

var c = a/b; //結果0.7789473684210526
var d = Math.round(c * 100) / 100; //結果0.78

これで良いかと思ったのですが
たまたま、以下の計算をしたら

var aa = 69.615;
var bb = Math.round(aa * 100) //結果0.6961499999999999
var cc= bb / 100; //結果69.61

となりこのパターンでは誤差が出てしまいます。正しい値は69.62

では、最初のロジックも四捨五入する為に*100をしてるので
誤差が出てしまうと言う事ですよね。

これの解決方はどのようにすれば良いのでしょうか?
引用返信 編集キー/
■51829 / inTopicNo.2)  Re[1]: JavaScriptの小数計算の誤差
□投稿者/ 魔界の仮面弁士 (1713回)-(2010/07/21(Wed) 20:16:46)
2010/07/21(Wed) 20:17:20 編集(投稿者)

# タイトルを修正しています。<少数→小数

> これの解決方はどのようにすれば良いのでしょうか?
手間はかかりますが、元データを工夫して、常に整数のみで演算するようにするか、
あるいは、数値を文字列(数字の並び)に置き換えて「筆算」の要領で自前処理すれば
10 進数としての誤差は発生しないはずです。

このほか、toFixed を使うことで誤差を目立たなくさせるという手法もありますが、
確実な方法であるとはいえないため、個人的にはあまりお奨めしません。
http://msdn.microsoft.com/ja-jp/library/5tbc0kce.aspx
http://d.hatena.ne.jp/onozaty/20070512/p1
http://www.geocities.co.jp/SiliconValley/4334/unibon/javascript/index.html

あとは、Java の BigDecimal クラスに相当する互換ライブラリを
JavaScript で実装した物があるので、そういった物を利用するとか。
http://stz-ida.de/index.php?option=com_content&view=article&id=18&Itemid=32


> 小数点以下二位で四捨五入をする必要があります。
あれ。その仕様の場合、結果は小数第一位までの概数になるべきでは無いでしょうか。

結果が百分の一の位まで必要になるのであれば、
 「小数点以下二桁未満で四捨五入」
 「小数点以下三桁以下を四捨五入」
 「四捨五入して小数第二位まで求める」
 「小数第三位で四捨五入」
 「小数第三位を四捨五入」
 「四捨五入して小数第二位まで求める」
などの表現が思い浮かびますが…そういえば、どのように表現するのが正しいのでしょうね。


> このパターンでは誤差が出てしまいます。
以下、ご存知かもしれませんが:

ECMA-262 を見る限り、JavaScript (というか ECMAScript) の仕様上では、
これらの数値は 64ビットの浮動小数点型として扱われているはずです。
そして浮動小数点数というものは、内部的には 2 進数表現で管理されています。

たとえば「10÷3」の場合、3 進では 10.1 という割り切れる値として表せるのですが、
10 進では 3.3333333…、2 進では 11.010101…となり、有限の桁数内では表現しきれません。
一方、「1÷2」であれば、2 進や 10 進では問題無いですが、3 進では表現できません。

このような理由から、JavaScript においては、0.5 や 0.75 などの数値であれば
誤差なく表わせますが、0.1 や 0.6 といった値については、実際には
僅かな誤差が生じているわけです。

たとえば当方環境においては、
var x = 0;
var y = 0.1;
while(x < 100) { x += y; }
の場合、最終的に x.toString() の結果は
「100.09999999999859」になりました。(IE / Firefox / WSH)
引用返信 編集キー/
■51854 / inTopicNo.3)  Re[2]: JavaScriptの小数計算の誤差
□投稿者/ まっち (5回)-(2010/07/22(Thu) 19:24:58)
やはり簡単にはいきそうに無いですね。

ライブラリは試してみました。 ちょっとテストした感じでは
問題無く動いているのですがどこまで信用してよいか
微妙なとこですよね。

丁寧に回答ありがとうございました。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -