有没有办法将浮点数映射到整数或无符号整数,这样除了NaN,订单会被保留?
因此,如果a和b是浮点数,而F是映射函数,
a< b表示F(a)< F(b)中 和 a == b表示F(a)== F(b)
答案 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单一,相同的字节顺序和浮点数和整数的相同地址空间等。