序列化浮点数

时间:2012-09-19 10:31:37

标签: serialization floating-point floating-point-precision

我正在搜索几个论坛,以获得有关如何序列化浮点数的一些想法,我碰巧遇到了以下代码。

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(独占)之间的值。

对于Eg:  frexp()返回0.81

ldexp(0.81,24) - &gt; 19.44当分配给unit_32时,它将被截断。

我没有看到这背后的逻辑。有人可以为我澄清一下吗?

1 个答案:

答案 0 :(得分:2)

ldexp(.81f, 24)不产生19.44;它产生13589545.代码的设计使得ldexp总是产生一个小于2 24 的整数,并且在mant中准确地捕获有效数字(应该被称为significand,因为它不是尾数。)

此代码不适用于负零,次正规,无穷大或NaN。