49422


すみません。[前回質問](https://ja.stackoverflow.com/questions/49377/javascript%E3%81%AE%E6%8E%9B%E3%81%91%E7%AE%97%E3%81%AE%E7%B5%90%E6%9E%9C%E3%81%8C%E8%A8%88%E7%AE%97%E6%A9%9F%E3%81%AE%E7%B5%90%E6%9E%9C%E3%81%A8%E7%95%B0%E3%81%AA%E3%82%8B%E3%81%AE%E3%81%AF%E3%81%AA%E3%81%9C%E3%81%A7%E3%81%99%E3%81%8B)の続きになります。

JavaScriptで小数点を扱う四則演算をしようとすると、どうすればよいでしょうか？  
前回コメントにて[decimal.js](https://github.com/MikeMcl/decimal.js)をおしえていただきましたが、[math.js](http://mathjs.org/)とはどう違うのでしょうか？

ご教授おねがいします。


CC BY-SA 4.0
2018-10-17T07:28:17.080
49381
2018-10-18T14:33:44.590
27196
question
javascript
JavaScriptでの小数点の扱いについて


decimal.jsはいわゆるdecimal型と呼ばれるデータ型を使用するためのライブラリです。  
math.jsはdouble型を使用して高速に演算するためのライブラリです。

この違いを理解するにはdouble型を説明したほうが早いかもしれません。  
double型は倍精度浮動小数点型とも言います。名前に小数点と入っていますが、きれいな10進数小数を扱うための型ではありません。

<https://ja.wikipedia.org/wiki/%E6%B5%AE%E5%8B%95%E5%B0%8F%E6%95%B0%E7%82%B9%E6%95%B0>  
上記のリンクに記されている通り倍精度浮動小数点数では、一つの数字のために  
符号(±)に1ビット、指数(範囲の広さ)に11ビット、仮数(精度)に52ビット、計64ビット(8バイト)使用します。  
仮数52ビットが有効桁数、つまり精度のために使用可能なビット数です。(けち表現による隠れビットも本当はありますが、ここでは述べません。)  
また全ての数を **2進数** として記録し解釈します。( **10進数を表現するためのデータ型ではない** のです。)  
52ビットで表現可能な数の種類は、2^52 = 4×2^50 ≒4×10^15のパターンあり、逆に言うと4×10^15程度のパターンしかないです。
**double型の有効精度は10^-15程度** だと覚えておくと役に立つこともあるでしょう。

例えばピザを2等分、4等分、8等分、・・・、2^52等分したとしてもピッタリ10等分にはならないですよね。  
2^52等分したピザをかき集めて10等分したピザにかなり近づけることはできますが、ピッタリ10等分にはなりません。それが前回の質問において誤差が発生した理由です。ピザカッターを入れる回数(≒仮数のビット数)をどれだけ増やしてもやはり10等分にはならないのです。

科学計算ではこの誤差を受け入れます。科学計算がデータに求める要件は効率よくデータが格納でき、かつ処理速度が十分速いことです。そのためには2進数でデータを表現するのが効率的なのでdoubleはそのように設計されています。

一方でdecimal型は最初から10進数を前提としてデータ型が構成されています。10等分できるピザカッターがあれば、 **完全に**
公平にピザを分割できるわけですね。ただし例えば0.000000000000000001を表現するためにはそれだけビット数が必要になります。実装系によりますが、decimalにも精度の限界はあります。(おおよそ20桁～30桁ぐらいが主流のようです)。bigdecimalとか呼ばれる可変長バイトのdecimalを使用すると、無限に近い精度を得ることもできると思いますが、実用的ではありません。精度を求めると計算速度が大きく低下するのです。


CC BY-SA 4.0
2018-10-18T14:33:44.590
49422
2018-10-18T14:33:44.590
25980
49381
answer