IEEE 754 floating-point “double format” ビットレイアウトがどうなっているかを表示するプログラムを作成してみた。
符号部は正の数だと0で負の数だと1が入り、指数部に入っている値には1023が加算されているようだ。仮数部には小数部分が2進数で入っているので1を加算しないといけないようだ。とりあえず、1E1の値を知りたかったので、それと10の内部表現が一致していたことだけは確認したが、その他の事項についてはまだ未確認な点が多い。1.0, 2.0, 4.0, 0.5, 0.25あたりを試すと良さそうだ。指数部の値によって正規化数か非正規化数かが決まって、計算が変わるらしいことまではわかったが、眠くなったので詳細はまだみていない。なんとなく正規化数については対応できていそうだが非正規化数は駄目そう。まだまだつめが甘そうだ。
と思いながらJavaFAQを見ると、浮動小数の表記方法を示す IEEE754 とは何ですか?という質問と答が、ずばり載っていた。…素晴らしいですJavaFAQ… でも指数部で1023を引いていないバグと非正規化数の考慮がされていないのを発見。指摘しておくのがいいのだろうけど、活動停止しているからどうしよう…とりあえずMLには投稿しておいた。
private double d;
private boolean sign; // true:plus or zero/false:minus
private long exponent;
private String mantissa;
private String longBit;
public ParseDouble(String s) {
d = Double.parseDouble(s);
longBit = Long.toBinaryString(Double.doubleToLongBits(d));
int longBitLength = longBit.length();
for (int i=64 ; i>longBitLength ; i–) {
longBit = “0”+longBit;
}
String ssign = longBit.substring(0, 1);
if (d == 0) { sign = true; }
else if ( “0”.equals(ssign) ) { sign = true; }
else { sign = false; }
s = longBit.substring(1, 12);
exponent = Long.valueOf(s, 2).longValue() – 1023;
mantissa = “1.”+longBit.substring(12, 64);
}
public double getData() { return d; }
public String getLongBit() { return longBit; }
public boolean getSign() { return sign; }
public long getExponent() { return exponent; }
public String getMantissa() { return mantissa; }
public static void main(String[] args) {
ParseDouble d = new ParseDouble(args[0]);
System.out.println(“data:”+d.getData());
System.out.println(“bit image:”);
System.out.print(“—6”);
System.out.print(“