end0tknr's kipple - 新web写経開発

http://d.hatena.ne.jp/end0tknr/ から移転します

66.9*100=6690.000000000001 って丸め誤差? いや IEEE 754 の仕様でした

http://blog.asial.co.jp/1191
偶然、↑このエントリを読んで、「66.9*100 の程度の桁数で丸め誤差でるの?」と思いましたが、js 的に浮動小数点型は、javaBigDecimal 実装の bigdecimal.js を使うのがよさそ。

mathcontext.js と bigdecimal.js は、例えば、次のurlからダウンロードできます。
http://code.google.com/p/gwt-math/source/browse/trunk/gwt-math/src/main/resources/com/googlecode/gwt/math/public/js/mathcontext.js?r=9

※乗算のmultiply() 以外にも、多くのmethodがあるので、srcを読んだ方がよさそうですね。
※SalesCube でも使用されているので、公開されているsrcが参考になります

<html>
<head>
<!-- http://code.google.com/p/gwt-math/source/browse/trunk/ -->
<!--   gwt-math/src/main/resources/com/googlecode/gwt/math/ -->
<!--   public/js/mathcontext.js?r=9 実際には1行のurlです -->

<script type="text/javascript" src="mathcontext.js"></script>    
<script type="text/javascript" src="bigdecimal.js"></script>    
<script>
 // http://blog.asial.co.jp/1191 によれば、 IEEE 754 の仕様らしい
 function calc_decimal_1(){
   console.log(66.9 * 10);	// = 669
   console.log(66.9 * 100);	// = 6690.000000000001
 }

 function calc_decimal_2(){
   var val_1_1 = new BigDecimal("66.9");
   var val_1_2 = new BigDecimal("10");
   console.log( val_1_1.multiply(val_1_2).toString() );
   var val_2_1 = new BigDecimal("66.9");
   var val_2_2 = new BigDecimal("100");
   console.log( val_2_1.multiply(val_2_2).toString() );
 }
</script>
</head>

<body>
  <button type="button" onClick="calc_decimal_1()">
    通常の小数計算
  </button>
  <button type="button" onClick="calc_decimal_2()">
    bigdecimal.jsによる小数計算
  </button>
</body>
</html>