浮動小数点数内部表現シミュレーター

数値リテラル→IEEE754内部表現

すると…

IEEE754単精度(float, 32bit = 4Byte)では…


指数部
exponent
8
仮数部
fraction
23
 
 

IEEE754倍精度(double, 64bit = 8Byte)では…


指数部
11
仮数部
52 (うち20)
 
 
仮数部
52 (うち32)
 
 

sample

IEEE754内部表現→数値リテラル

で、
符号部 、 指数部 仮数部 の値を すると…
2進
10進
16進
指数
sample

概要

浮動小数点数(IEEE754)の内部表現をシミュレートします。

計算過程のヒントをConsoleに出力しています。計算過程を確認したい方は、 F12で開発者ツールを開いて実行してみてください。

補足

コメント

IPAの情報処理試験の勉強用としてと、JavaScriptで小数の計算の誤差が なぜ発生するのかきちんと理解したかったので作成しました。 おかげで「0.1 + 0.2」がなぜ0.3にならないのかが、ビット単位で把握できました。

丸め方式の1つに、丸める前の実数と距離的に最も近い数に丸める、 RN (Round toNearest)方式があります。 m進数で「m/2-1捨m/2入」、10進数だと四捨五入、2進数だと0捨1入になります。 誤差をできるだけ小さくする方法として利用されます。

ただしIEEE754のRN方式は偶数丸めと呼ばれる、2つの桁を使って判断する方法を採用しています。 「00」→「00」、「01」→「00」、「10」→「10」、「11」→「100」。

0.1も0.2も、倍精度浮動小数点数で表すと 無限小数でかつ仮数部の最下位ビットが0捨1入で繰り上がった値になります。 その結果0.1と0.2を足すと、0.3より少し大きい値になってしまうのです。

※このページの機能は、一部の機能に若干バグがあります。ご了承ください。 このページの機能は、JavaScriptの組込みの機能も利用し処理をしており、極端に大きい・小さい数値では JavaScriptの処理で誤差が発生するため、正しく表現できない現象を確認しています。 現状で把握しているバグの発生する数値とは、「数値リテラル→IEEE754内部表現」時の「5e-324 (Number.MIN_VALUE)」と 「IEEE754内部表現→数値リテラル」時の「9007199254740992 (Number.MAX_SAFE_INTEGER + 1)」です。

9007199254740992はMAX_SAFE_INTEGERより1大きい数ですが、toStringでは完全に変換できます。 しかし、toLocaleStringだと誤差が発生し、元の値より2少ない「9007199254740990」になります。 このページでは、大きな数でも指数表現ではなく10進数で表現したいので、 内部でtoLocaleStringを使っています。結果として、「MAX_SAFE_INTEGER」は9007199254740991になり、 それより大きい「MAX_SAFE_INTEGER + 1」は9007199254740990と、大小関係が逆転する現象が発生します。 SAFE_INTEGERの範囲外なので、正しく変換できないケースがあるのは仕方がないかもしれませんが、 MAX_SAFE_INTEGERより大きな数が、MAX_SAFE_INTEGERより小さく表現されてしまうのはとても違和感があります。 JavaScriptの組込みの機能を利用せず、自前で処理すれば解消できるはずですが、今のところ対応予定はありません。

「5e-324 (Number.MIN_VALUE)」は、0.0000000000...と0が300以上続くとても小さな数です。 この数をJavaScriptの機能で2進数表現にすると「0」になってしまいます。 そのためJavaScriprの基本的な機能の範囲で実装しようとすると無理そうなので半ばあきらめています。 この処理については、将来的にひらめいたらいずれ実装するかもしれません。

関連

ちょこっとアンケート&メッセージ

このページに関するちょっとした感想または、要望、バグ・間違いの指摘、 質問・その他お問合せ等は、下記の送信欄からお送りください。 返信をご希望の方は「こちらのページ」からメッセージをお送りください。

「このページはお役に立ちましたか?」のアンケートとメッセージのどちらか一方でかまいません (両方書いていただけるとよりうれしいです)。お気軽にご利用ください (感想・フィードバック・どんな用途で使用したかなどをいただけると作成・運営の励みになります!)


このページはお役に立ちましたか?