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

数値リテラル→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)の内部表現をシミュレートします。

補足

コメント

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.2を足すと、0.3より少し大きい値になってしまうのです。

当初は計算をすべてJavaScriptで行っていました。しかし仮数部の組み立てにtoString関数で変換して 仮数部を超える情報を切り捨てるという実装をし、偶数丸めを実装しなかったため、 仮数部の桁では正確に表現しきれない値では1/4の確率で本来の値と異なるバグがありました。

いつか直そうかと思いつつ長期放置していたのですが、2021/04に結果が間違っているとのメッセージが来ました。 一応バグがある旨は明記していたのですが、だとしてもやはりバグは少ないに越したことはないので、 これを期にJavaScriptでの自前処理をやめ、PHPのpack関数などを使い変換することにしました。

この修正によりバグはなくなった、…はずです…。もしバグを発見した場合にはご連絡お願いします。

関連・参考リンク

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

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

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


このページはお役に立ちましたか? 認証コード 必須
画像のひらがな一文字を入力してください。拗音・促音・濁点・半濁点はありません。