将大 int 转换为浮点数,而不舍入 c++
Convert large int to float without rounding c++
有没有一种快速干净的方法可以将int32_t(或更大(转换为浮点数中不大于int32_t中存储的原始值的最大可表示值?
根据IEEE754标准(在维基百科 https://en.wikipedia.org/wiki/Single-precision_floating-point_format 上只读(,大整数的转换是通过四舍五入到最接近的 2 次方的倍数来完成的。哪个幂取决于该值的大小。
但是,我想知道,是否可以将这种转换为"最大浮点数而不是更大",并以干净的方式进行,而无需复杂的构造,理想情况下是通过设置一些标志或使用一些内置指令?
编辑:我有一个值x_int存储在int32_t或int64_t中,我想将其转换为浮点值x_float,以便对于这些值(数学上,而不是在编程滞后(
x_int>=x_float
总是正确的。int32_t可能的解决方法是使用双精度,但我不确定int64_t。
行为可能取决于有效的编译器选项。例如,在 msvc 中/fp:fast
为了速度而牺牲了正确性。如果这不是您想要的,请指定/fp:strict
或/fp:precise
(默认值(。在Clang上,-menable-unsafe-fp-math
做了类似的事情。
浮点舍入模式由fesetround
控制。
- http://www.cplusplus.com/reference/cfenv/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
- 将大 int 转换为浮点数,而不舍入 c++
- 浮点数学运算后舍入不一致
- C++长双精度格式而不舍入
- 为什么这个C++程序舍入双值而不打印整个字符串
- 方便的标志处理,所有标志都不能放入64位
- 对应该返回的双精度变量进行舍入,而不是打印
- C++舍入数字,不带上限或下限
- 不需要的舍入C++
- 浮点舍入不正确
- 如何在不舍入的情况下以C++显示固定位数
- cvRound() 中的 x64 舍入不一致 (_mm_cvtsd_si32)
- 清理值而不向上或向下舍入
- 舍入误差在DFT中给出不正确的tesult
- 不带逻辑运算符的舍入整数除法
- 当不需要时,C++双舍入
- 浮点数和由于舍入行为导致的不正确结果
- 用两个小数求3个数字的平均值(不舍入!)
- 在c++中,如何使用iostream和iomanip在不显示数字的情况下进行舍入?
- c++内部可以表示的0到1之间不舍入的最大和最小的数是什么?
- "floor"是否有可能由于浮点舍入误差而返回不准确的结果?