将big int转换为float而不舍入c ++

时间:2018-05-23 12:41:12

标签: c++ type-conversion

是否有一种快速而干净的方法将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。

1 个答案:

答案 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;
}

性能方面,将prevmodemode进行比较可能会或可能不会更好。如果它已经是正确的,您不需要设置或恢复它。比较是否比设定/恢复更快或更慢我不知道。

示例输出(在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