JavaScriptでの小数点の扱いについて

投稿者: Anonymous

すみません。前回質問の続きになります。

JavaScriptで小数点を扱う四則演算をしようとすると、どうすればよいでしょうか?
前回コメントにてdecimal.jsをおしえていただきましたが、math.jsとはどう違うのでしょうか?

ご教授おねがいします。

解決

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を使用すると、無限に近い精度を得ることもできると思いますが、実用的ではありません。精度を求めると計算速度が大きく低下するのです。

回答者: Anonymous

Leave a Reply

Your email address will not be published.