« コンパスの出力は正しいようだ | トップページ | 朱に交われば赤くなる »

2008年10月15日 (水)

IEEE 754形式のfloatをCCS PCMのfloatに変換する

掲題の件、何が悪かったか判明しました。簡単に言うと、「シフト演算子とビット演算子の優先順位を私が間違えていたことにより、仮数部が正しく変換されていなかった」というのが原因でした。

参考までに、その変換を行う関数のソースコードをUpしておきます。

/**

    CCS-PCMのfloatフォーマットに変換する。
   
    @note CCS-PCMのfloatフォーマットが一般的なIEEE 754とフォーマットが異なるので
    この変換関数を作成した。
*/

float convertToCCSFloat(unsigned char d[4])
{
    // IEEE Std 754-1985 float format (big endian)
    //
    // 31............24...23............16...15.............8...7..............0
    // S E E E  E E E E   E F F F  F F F F   F F F F  F F F F   F F F F  F F F F
    //
    // where
    //     E : 8bit exponent with bias of 7F
    //    S : Sign bit
    //    F : 23bit Mantisa
    // Number = (-1)^S * 1.F * 2^(E-127)   
   
   
    // CCS-PCM float format
    // (Reference: CCS-PCM C Compiler Reference Manual, Common Questions and Answers)
    //
    // 31............24...23............16...15.............8...7..............0
    // E E E E  E E E E   S F F F  F F F F   F F F F  F F F F   F F F F  F F F F
    //
    // where
    //     E : 8bit exponent with bias of 7F
    //    S : Sign bit
    //    F : 23bit Mantisa
    // Number = (-1) ^S * 1.F * 2^(E-127)

    float number = 0;
    unsigned char *ptr;

    ptr = (unsigned char *)(&number);

    *(ptr + 0) = ((0x7F & d[0]) << 1) | ((0x80 & d[1]) >> 7);
    *(ptr + 1) = (0x80 & d[0]) | (0x7F & d[1]);
    *(ptr + 2) = d[2];
    *(ptr + 3) = d[3];

#if 0
//    printf(" data = %02X%02X%02X%02X \r\n", d[0], d[1], d[2], d[3]);
//    printf(" conv = %02X%02X%02X%02X \r\n", *(ptr), *(ptr+1), *(ptr+2), *(ptr+3));

    printf(" number = %f \r\n", number);
#endif   

    return number;
}

バグがあったのは、上記のコードの
    *(ptr + 0) = ((0x7F & d[0]) << 1) | ((0x80 & d[1]) >> 7);  // 正しい
の部分です。これを
    *(ptr + 0) = ((0x7F & d[0]) << 1) | (0x80 & d[1] >> 7);  // これじゃ駄目
こう書いていました。下の書き方では、>> が先に評価されてしまうため、0x08 & d[1] >> 7 は常に0になってまう、というのが不具合の原因でした。

« コンパスの出力は正しいようだ | トップページ | 朱に交われば赤くなる »

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/167990/42791905

この記事へのトラックバック一覧です: IEEE 754形式のfloatをCCS PCMのfloatに変換する:

« コンパスの出力は正しいようだ | トップページ | 朱に交われば赤くなる »

最近の写真