【问题标题】:Correctly converting floating point in C++在 C++ 中正确转换浮点数
【发布时间】:2016-10-27 11:13:02
【问题描述】:

告诉 C++ 编译器“只警告我不知道的浮点转换”的正确/推荐方式是什么?

在 C 语言中,我将启用与浮点转换相关的警告,然后使用显式 C 样式强制转换来消除与受控制的转换相关的警告。

例如,计算a*a*a - b*b 很容易在单精度浮点中溢出,因此您可能希望以双精度计算它,以后只使用单精度:

double a = 443620.52;
double b = 874003.01;
float c = (float)(a*a*a - b*b);

上述 C 风格的显式转换将使编译器关于从 double 转换为 float 的警告静音。

阅读有关强制转换的 C++ 文档,我得出结论,在 C++ 中执行此操作的正确方法如下:

double a = 443620.52;
double b = 874003.01;
float c = static_cast<float>(a*a*a - b*b);

但是,这真的是在 C++ 中执行此操作的正确方法吗?

我理解 static_cast 语法为 ugly on purpose 背后的基本原理,因此您可以尽可能避免强制转换。

是的,我可以省略显式强制转换为浮动。但是然后我需要禁用告诉我精度损失的编译器警告(否则我会收到许多不相关的警告,这些警告会让人很难注意到真正相关的警告)。如果我禁用 fp 相关的编译器警告,当我在其他代码位置错误地丢失精度时,我将失去被警告的可能性。

那么,在 C++ 中进行浮点转换的正确方法是什么?

【问题讨论】:

    标签: c++ casting floating-point


    【解决方案1】:

    是的

    float c = static_cast<float>(a*a*a - b*b);
    

    是在 C++ 中显式转换为 float 的正确方法。你也可以这样做:

    float c = (float)(a*a*a - b*b);
    

    但是使用这样的“C 风格”转换是不好的风格,因为 static_cast 将隐藏比 C 风格更少的错误。

    或者,如果你经常这样做,你可以定义一个函数:

    inline float flt(double d){return static_cast<float>(d);}
    

    然后你可以写:

    float c = flt(a*a*a - b*b);
    

    它比原来的 C 更加紧凑(并且将被优化为空)。

    【讨论】:

    • 但是从doublefloat 的转换在浮点编程中很常见。 static_cast“丑陋”将是一种不应有的惩罚恕我直言,因为演员不仅是合法的,而且是必要的,而且无论编码风格多么好,都无法避免。
    • 非常感谢,您关于定义函数的建议完全符合我的需求,而且是简洁的 C++ 编码风格。
    【解决方案2】:

    据我所知,有三种不同的方法可以避免警告:

    1. C 风格转换
    2. static_cast
    3. 构造函数式转换(例如float c = float(a*a*a-b*b)

    在下面的代码示例中,c1c2c3 避免出现警告:

    int main()
    {
      double a = 443620.52;
      double b = 874003.01;
    
      // These three versions avoid the conversion warnings:
      float c1 = (float)(a*a*a - b*b);
      float c2 = static_cast<float>(a*a*a - b*b);
      float c3 = float(a*a*a - b*b);
    
      // Only these two give conversion warnings:
      float c4(a*a*a - b*b);
      float c5 = a*a*a - b*b;
    
      (void)c1; // Just to avoid unused-variable warnings
      (void)c2;
      (void)c3;
      (void)c4;
      (void)c5;
    }
    

    只有c4c5 会触发警告。 Check the live demo查看结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多