2010年9月6日月曜日

80bit浮動小数点数?

 行き詰った。
テスト用のaiffファイルの80bit浮動小数点数データは
0x400EAC44000000000000
で、前半16bitに符号と仮数。後半64bitが指数になる。
 対して普通のdouble、つまり64bit浮動小数点数は
0x40E5888000000000
で、前半12bitに符号と仮数、残りが指数となる。 
ちなみにこの数値は44100。
 こねくり回しても同じ値にならなくてこまってる。
そもそも指数部は違うパラメータにならないと思うがいったいどういう。
 
 でも仮数部は同じ値なんだよね。
0x400E - 16383 = 15
0x40E - 1023 = 15
で。かえってややこしい。
 さらにいえば80bitの指数0xAC44は44100で正しいはずだけど、
64bitdoubleの指数部をバイナリそのまま覗くと上記の数値なんだよなあ。
なんか不思議な力が働いてるのか? うーん。
 2進でみると
0xAC44 = 1010110001000100
0x5888 = __101100010001000
で、二桁ずらせば一部一致する。すごく怪しい。
 
 だんだん面倒くさくなってきた。
サンプリングレートなんて44.1Kとか22.05Kとか11.025Kとか大体固定だろうから、
10Byteデータが一致するかどうかでチェックしたほうが早いかも。
 
/** 2011-04-11追記 */
浮動小数点演算ではまった話 - bkブログ
IEEE 754 の 32ビットと 64ビットの浮動小数点数には仮数部の前に暗黙の 1 (暗黙ビット) が置かれることになっていますが、80ビットの浮動小数点数には 歴史的事情により 暗黙ビットは存在しません。
 と、半年たって知った。この辺がカギになるんだろうが今のところ手を付けてない。
 
 64bitのほう、44.1Kを手で計算した。
(2)0100 0000 1110 0101 1000 1000 1000 0000 ...
となり、0x40E58880...と実際に得られるデータと一致。
 それから80bitのほうを手で計算。そのとき仮数部の先頭1をカットしない場合
(2)0100 0000 0000 1110 1010 1100 0100 0100 0000...
となり、0x400EAC440...となった。やった!
 
 というわけで80bit浮動小数点数を64bitにするとき、
仮数部先端の1を除去すれば変換可能のようだ。

0 件のコメント: