在 C++ 中正确转换浮点数

Posted

技术标签:

【中文标题】在 C++ 中正确转换浮点数【英文标题】:Correctly converting floating point in 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++ 中进行浮点转换的正确方法是什么?

【问题讨论】:

【参考方案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】:

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

    C 风格转换 static_cast 构造函数式转换(例如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查看结果。

【讨论】:

以上是关于在 C++ 中正确转换浮点数的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中决定普通浮点数的代码? [复制]

在 C++ 中将浮点数转换为 std::string

可以采用整数或浮点数或双精度数或任何其他可转换为浮点数的 C++ 函数

在 Swift 中将半精度浮点数(字节)转换为浮点数

C++如何用cout控制浮点数输出的位数?

正确转换浮点数?