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 回答