正确转换C ++中的浮点

时间:2016-10-27 11:13:03

标签: c++ casting floating-point

告诉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 ++中浮点转换的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

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

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

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

但使用&#34; C风格&#34;这样做就是糟糕的风格,因为static_cast会隐藏比C风格更少的错误。

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

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

然后你可以写:

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

比原始C更紧凑(并且将被优化为无)。

答案 1 :(得分:0)

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

  1. C-style cast
  2. static_cast
  3. 构造函数式转换(例如float c = float(a*a*a-b*b)
  4. 在下面的代码示例中,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查看结果。