1

浮動小数点数をシリアル化する方法についていくつかのアイデアを得るためにいくつかのフォーラムを検索していたところ、たまたま次のコードに出くわしました。

oxdrstream&
oxdrstream::operator<<(
    float               source )
{
    BytePutter          dest( *this ) ;
    bool                isNeg = source < 0 ;
    if ( isNeg ) {
        source = - source ;
    }
    int                 exp ;
    if ( source == 0.0 ) {
        exp = 0 ;
    } else {
        source = ldexp( frexp( source, &exp ), 24 ) ;
        exp += 126 ;
    }
    uint32_t            mant = source ;
    dest.put( (isNeg ? 0x80 : 0x00) | exp >> 1 ) ;
    dest.put( ((exp << 7) & 0x80) | ((mant >> 16) & 0x7F) ) ;
    dest.put( mant >> 8 ) ;
    dest.put( mant      ) ;
    return *this ;
}

なぜこれを行う必要があるのか​​ わかりません

source = ldexp( frexp( source, &exp ), 24 ) ;

frexp() は、0.5 (包括的) から 1 (排他的) までの値を返します。

例: frexp() は 0.81 を返します。

ldexp( 0.81, 24 ) --> 19.44 であり、 unit_32 に割り当てられると切り捨てられます。

この背後にあるロジックはわかりません。誰かが私のためにこれを明確にすることができますか?

4

1 に答える 1

2

ldexp(.81f, 24)19.44を生成しません。13589545を生成します。コードは、ldexpが常に2 24未満の整数を生成し、仮数を正確にキャプチャするように設計されています(仮数ではないため、これをmant呼び出す必要があります)。significand

このコードは、負のゼロ、非正規化数、無限大、またはNaNでは機能しません。

于 2012-09-19T11:24:17.233 に答える