c++ - 使用整数立即值和警告初始化 float

标签 c++ int type-conversion floating-point-precision

在我的代码中,我用 0、1 和 2 值(或其他小整数)初始化了很多 float 。虽然 GCC 不会为此生成警告,但 MSVC 会生成警告。所以我用 0.f 替换了所有的 0,用 1.f 替换了 1,等等......同时用 0.5 初始化一个 float 发出警告,我用 0.5 替换了它f.

虽然我完全理解执行 float f=someIntfloat f=someDouble 应该会产生警告,因为在某些情况下精度会丢失,编译器应该足够聪明知道 0、1、2 和 0.5 是精确的浮点值。而且我的代码的可读性要差得多......

MSVC 没有使用某些标准吗?我应该让他提示还是降低我的代码的可读性?

谢谢!

最佳答案

[...] the compiler should be smart enough to know that 0, 1, 2 and 0.5 are exact float values.

可能是这样,但您真的希望编译器使用该知识来抑制警告吗?考虑以下代码片段:

double fun()
{
    float calculated = UNIVERSAL_BASE_VALUE;
    // Do some calculations.
    return calculated;
}

假设 UNIVERSAL_BASE_VALUE 是在某处头文件中定义的常量。也许它的类型是double。但它的值可能是 0.5,这是一个精确的 float 值,因此编译器可以使用它的知识来抑制这种情况下的警告。

现在快进几年。这个有趣的功能暂时没有被触及,但业务发生变化,有人想尝试将 UNIVERSAL_BASE_VALUE 的定义从 0.5 更改为 0.51。突然有一个针对该函数的编译器警告,该函数多年来一直很稳定。为什么是这样?没有逻辑上的变化,只是一个小的数据变化。然而,该数据更改为 UNIVERSAL_BASE_VALUE 提供了一个无法在 float 中准确表示的值。编译器不再对转换保持沉默。经过调查,发现这些年来calculated的类型一直是错误的,导致fun()返回的结果不准确。是时候责怪编译器太聪明了吗? :)

请注意,如果将 UNIVERSAL_BASE_VALUE 替换为文字 0.5,您会遇到类似的情况。它只是让结局不那么戏剧化,而总体要点仍然成立:聪明可能会让错误溜走。


编译器警告旨在提醒您注意潜在的错误。这不是一门精确的科学,因为程序员的意图很难推断,尤其是当编码风格不同时。没有涵盖编译器可能选择发出的所有警告的综合标准。当出现误报时,程序员需要根据具体情况做出判断。我可以想到四种基本方法供您选择。

  1. 关闭警告(因为它对您的代码没有真正帮助)。
  2. 接受编译时会生成警告(这不是一个好的选择)。
  3. 更改编码风格以适应警告(耗时)。
  4. 向编译器的开发人员发牢骚(呃……礼貌地要求更改;不要发牢骚)。

不要选择选项 2。这意味着累积警告,人类学会忽略。一旦您积累了足够多的“已接受”警告,就很难发现弹出的其他警告。他们迷失在人群中,因此达不到预期目的。

请注意,编译器倾向于支持仅针对某些文件的某些行抑制某些警告。这给出了选项 1 和选项 2 之间可能可以接受的折衷方案。

在您的情况下,您需要针对您的代码库评估此警告。如果它通过发现错误来提供值(value),那么您应该选择所谓的“可读性较差”。 (它的可读性并没有降低,但确实需要时间来适应它。)如果警告没有提供足够的值(value)来保证样式更改,请关闭警告。

关于c++ - 使用整数立即值和警告初始化 float ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19956575/

相关文章:

c++ - 如何从 post 请求的 HTTP 正文中提取二进制文件内容?

c++ - 线程 vector 中的假缓存共享 C++

swift - Int 类型的变量不能分配给定义为 Int 的枚举

java - 如何将 Long 转换为 byte[] 并返回到 java

java - Java 中的等效数据类型

c++ - 将 const char* 转换为 vector<double> 更好的方法

c++ - OpenCV C++ 和 cvSmooth

c++ - 如何创建具有电视效果的图像?

java - 为 int 值设置限制

c# - AutoMapper:字符串到可为空的 int