c++之如何将整数转换为 float 并向零舍入

lovecherry 阅读:50 2024-06-20 12:54:19 评论:0

当整数转换为浮点数且该值不能直接由目标类型表示时,通常会选择最接近的值(IEEE-754要求)。
如果整数值不能直接由浮点类型表示,我想将整数转换为浮点并向零舍入。
例:

int i = 2147483647; 
float nearest = static_cast<float>(i);  // 2147483648 (likely) 
float towards_zero = convert(i);        // 2147483520 

请您参考如下方法:

从C++ 11开始,可以使用fesetround(),即浮点环境rounding direction管理器。有四个标准rounding directions,并且允许实现添加其他舍入方向。

#include <cfenv> // for fesetround() and FE_* macros 
#include <iostream> // for cout and endl 
#include <iomanip> // for setprecision() 
 
#pragma STDC FENV_ACCESS ON 
 
int main(){ 
    int i = 2147483647; 
 
    std::cout << std::setprecision(10); 
 
    std::fesetround(FE_DOWNWARD); 
    std::cout << "round down         " << i << " :  " << static_cast<float>(i) << std::endl; 
    std::cout << "round down        " << -i << " : " << static_cast<float>(-i) << std::endl; 
 
    std::fesetround(FE_TONEAREST); 
    std::cout << "round to nearest   " << i << " :  " << static_cast<float>(i) << std::endl; 
    std::cout << "round to nearest  " << -i << " : " << static_cast<float>(-i) << std::endl; 
 
    std::fesetround(FE_TOWARDZERO); 
    std::cout << "round toward zero  " << i << " :  " << static_cast<float>(i) << std::endl; 
    std::cout << "round toward zero " << -i << " : " << static_cast<float>(-i) << std::endl; 
 
    std::fesetround(FE_UPWARD); 
    std::cout << "round up           " << i << " :  " << static_cast<float>(i) << std::endl; 
    std::cout << "round up          " << -i << " : " << static_cast<float>(-i) << std::endl; 
 
    return(0); 
} 
在g++ 7.5.0下编译,生成的可执行文件输出
round down         2147483647 :  2147483520 
round down        -2147483647 : -2147483648 
round to nearest   2147483647 :  2147483648 
round to nearest  -2147483647 : -2147483648 
round toward zero  2147483647 :  2147483520 
round toward zero -2147483647 : -2147483520 
round up           2147483647 :  2147483648 
round up          -2147483647 : -2147483520 
  • 在g++下,省略#pragma似乎没有任何改变。
  • @chux正确评论了该标准未明确指出fesetround()影响static_cast<float>(i)中的舍入。为了确保设置的舍入方向会影响转换,请使用 std::nearbyint 及其-f和-l变体。另请参见 std::rint 及其许多特定于类型的变体。
  • 我可能应该查看格式说明符,以便为正整数和浮点数使用空格,而不是将其填充到前面的字符串常量中。
  • (我尚未测试以下代码段。)您的convert()函数类似于
    float convert(int i, int direction = FE_TOWARDZERO){ 
        float retVal = 0.; 
        int prevdirection = std::fegetround(); 
        std::fesetround(direction); 
        retVal = static_cast<float>(i); 
        std::fesetround(prevdirection); 
        return(retVal); 
    } 
    

  • 标签:C++
    声明

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    关注我们

    一个IT知识分享的公众号