是否有一种快速而干净的方法将int32_t(或更大)转换为浮点数不大于存储在int32_t中的原始值的最大可表示值?
根据IEEE754的标准(仅在维基百科https://en.wikipedia.org/wiki/Single-precision_floating-point_format上阅读),大整数的转换是通过舍入到2的幂的最接近倍数来完成的。哪个幂取决于该值的大小。
但是我想知道,是否可以将此转换为最大的浮点数不大于"相反,并在没有复杂结构的情况下以干净的方式执行此操作,理想情况下通过设置一些标志或使用一些内置指令?
编辑:我有一个存储在int32_t或int64_t中的值x_int,我希望将其转换为浮点值x_float,以便对于这些值(数学上,不在编程语言中)
x_int> = x_float
总是如此。 int32_t的可能解决方法是使用double,但我不确定int64_t。
答案 0 :(得分:2)
行为可能取决于有效的编译器选项。例如,在msvc中/fp:fast
牺牲了速度的正确性。如果这不是您想要的,请指定/fp:strict
或/fp:precise
(默认值)。在Clang上,-menable-unsafe-fp-math
做了类似的事情。
浮点舍入模式由fesetround
控制。
使用fegetround
检索舍入模式,以便稍后恢复,然后使用fesetround
设置所需的舍入模式(如果您的意思是最小,则为FE_TOWARDZERO
}或者FE_DOWNWARD
否则)然后将其投射到float
。最后恢复舍入模式。
inline float cast_with_mode(int32_t value, int mode){
int prevmode = fegetround();
if(prevmode == mode) return (float)value; // may be faster without this
fesetround(mode);
float result = (float)value;
fesetround(prevmode);
return result;
}
性能方面,将prevmode
与mode
进行比较可能会或可能不会更好。如果它已经是正确的,您不需要设置或恢复它。比较是否比设定/恢复更快或更慢我不知道。
示例输出(在Clang和G ++上相同):
Mode Value Value ResultBits Result Value
FE_TOWARDZERO: 2147483520 0x7fffff80 => 4effffff 2147483520.000000
FE_UPWARD: 2147483520 0x7fffff80 => 4effffff 2147483520.000000
FE_TOWARDZERO: 2147483584 0x7fffffc0 => 4effffff 2147483520.000000
FE_UPWARD: 2147483584 0x7fffffc0 => 4f000000 2147483648.000000