質問: すみません。前回質問の続きになります。 JavaScriptで小数点を扱う四則演算をしようとすると、どうすればよいでしょうか? 前回コメントにてdecimal.jsをおしえていただきましたが、math.jsとはどう違うのでしょうか? ご教授おねがいします。
回答: decimal.jsはいわゆるdecimal型と呼ばれるデータ型を使用するためのライブラリです。 math.jsはdouble型を使用して高速に演算するためのライブラリです。 この違いを理解するにはdouble型を説明したほうが早いかもしれません。 double型は倍精度浮動小数点型とも言います。名前に小数点と入っていますが、きれいな10進数小数を扱うための型ではありません。 上記のリンクに記されている通り倍精度浮動小数点数では、一つの数字のために 符号(±)に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を使用すると、無限に近い精度を得ることもできると思いますが、実用的ではありません。精度を求めると計算速度が大きく低下するのです。