double型で「1.1」と記録しました。
すると、16進数で、「9A 99 99 99 99 99 F1 3F」となっていました。
何故そうなるのか説明お願いします。
一言で言うと「IEEE754の倍精度浮動小数点形式で数値を表現しているから」です。
実際にやってみます。
http://pc.nikkeibp.co.jp/pc21/special/gosa/eg4.shtml
1.1をIEEE754倍精度浮動小数点数に変換する。
http://www.pat.hi-ho.ne.jp/ochiyasu/jouhou/2syu/jou-2-n_sinsu.ht...
の一番上にある方法で0.1(10進数)=0.000110011001100110011001....(以下ずっと1001が続く)と計算されるので
1.1(10進数) = 1.0001 1001 1001 1001 1001 1001 1001 1001 ...
これをIEEE754の形式にあわせると
符号は正なので0
指数部(2^n乗)のところがn=0なのでお約束で1023と表現する。1023(10進数)=3FF(16進数)=0011 1111 1111
仮数部は上のとおりで、1を省略して小数点以下だけを格納する方式なのであわせると
0011 1111 1111 0001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1010
3 F F 1 9 9 9 9 9 9 9 9 9 9 9 A
最後の1ビットは最近偶数丸めと呼ばれるやり方でで切り上げて9->Aとします。
これは 3F F1 99 99 99 99 99 9A です。
ここでIntel系のCPU(x86)はリトルエンディアン形式で数値を格納するので、バイトの順が入れ替わります。
http://tipsofvb.net/blogs/tips/archive/2005/07/12/97.aspx
http://www.wdic.org/w/TECH/%E3%83%AA%E3%83%88%E3%83%AB%E3%82%A8%...
逆に読めばいいので
9A 99 99 99 99 99 F1 3A
と格納される、というわけです。
IEEE 754 - Wikipedia
http://ja.wikipedia.org/wiki/IEEE_754
(少なくとも)C言語では、数値はコンピュータ内部では全て2進数で表現されています。
10進数の1.1は2進数では1.0001100110011001...となります。
さらに、浮動小数点(例えば345を3.45×10^2と表現する方法です。^は累乗記号)だと
1.0001100110011001...×2^0となります。
IEEE754という浮動小数点を2進数で表現する規格がありまして、この規格では64ビット浮動小数点(double型)は
符号部(1ビット)…値が正か負かを示す
指数部(11ビット)…桁数、累乗部分の指数を示す、実際の値に1023を加えた値
仮数部(52ビット)…小数点以下の部分を示す
の3つの組み合わせで表現されることになっています。(リンク先が詳しいです)
10進数1.1を例に取ると
符号部…正の値なので'0'
指数部…累乗の指数が0なので、1023を加えて2進数表現すると'01111111111'
仮数部…'0001100110011001100110011001100110011001100110011010'
(2進数表現では無理数なので最後は丸めてあります)
これらを繋げると
'00111111 11110001 10011001 10011001 10011001 10011001 10011001 10011010'
となり、16進数では
'3F F1 99 99 99 99 99 9A'
となります。
Windows系(正確にはCPU依存ですが)ではリトルエンディアンといわれるメモリ格納方式が採用されており、メモリへの格納は下位バイトからとなります。そのため順番が逆になり
'9A 99 99 99 99 99 F1 3F'
となります。
こちらもわかりやすい。有難うございます。
はてな凄い。分かりやすいです。有難うございました。