将32位浮点映射到32位整数

时间:2010-05-05 18:37:53

标签: c++ c floating-point

有没有办法将浮点数映射到整数或无符号整数,这样除了NaN,订单会被保留?

因此,如果a和b是浮点数,而F是映射函数,

a< b表示F(a)< F(b)中 和 a == b表示F(a)== F(b)

2 个答案:

答案 0 :(得分:12)

嗯,就在游戏编程宝石6中的DawsonCompare例程之外,它是一个正常的位转换,然后是符号翻转(因为负浮动顺序与负整数相反)。我会借用这个想法。

你有:

// utility
template <typename R, typename T>
R& bit_cast(T& pX)
{
    return reinterpret_cast<R&>(pX);
}

// int32_t defined in <boost/cstdint.hpp>. 
boost::int32_t float_to_int_bits(float pX)
{
    boost::int32_t x = bit_cast<boost::int32_t>(pX);

    if (x < 0)
        x = 0x80000000 - x;

    return x;
}

如果您可以保证int是32位,则可以使用它。


有趣的事实:本书继续使用它(注意,不是我提供的确切代码,因为我剥离了float-to-int部分)来比较浮点值和容差:

bool DawsonCompare(float pX, float pY, int pDiff)
{
    int x = float_to_int_bits(pX);
    int y = float_to_int_bits(pY);

    int diff = x - y;
    return abs(diff) < pDiff;
}

如果整数表示在一定范围内,则将浮点数与真实值进行比较。 (他使用1000作为一个很好的默认值。)一个名为LomontCompare的无分支版本提出了相同的想法,但你必须购买这本书。 :)

答案 1 :(得分:1)

只是为了从其他答案中消除潜在的慢if ......

int32_t float_to_int( float f ) {
    int32_t i = reinterpret_cast< int32_t& >( f );
    uint32_t sgn = static_cast< uint32_t >( i ) >> 31;

    return i ^ -sgn & numeric_limits<int32_t>::max();
}

请注意,与其他解决方案不同,这会错误地处理0-0。作为浮点数,它们比较相等,但在映射到整数后,它们分别变为0-1。作为数字行中的单个打嗝,如果没有分支指令,我认为处理这种情况并不容易。

当然,这假设是二进制补码算术,float是IEEE 754单一,相同的字节顺序和浮点数和整数的相同地址空间等。