整数变量与整数字面变化的乘法结果

integer variable versus integer literal changes result of multiplication

本文关键字:整数 结果 变量 数字 变化      更新时间:2023-10-16

我有一个非常有趣的错误,其中.498*2000产生995而不是996 - 但仅当2000将2000存储在整数变量中而不是简单的文字中时。我运行以下代码以确保我不会发疯,评论中显示了变量的结果。Dequeue和Peek是我正在使用的函数,它们返回Int16_t,尽管这似乎并不重要,因为C仍然是价值2000的INT。所有值既通过print语句确认,也可以通过GDB运行。

int a = buffer.dequeue();    // a = 0
int b = buffer.peek();       // b = 2000
int c = a + b;               // c = 2000
float d = .498*2000;         // d = 996
int e = static_cast<int>(d); // e = 996
int f = .498*2000;           // f = 996
int g = .498*c;              // g = 995 WHY??????

我真的不明白这里发生了什么,非常感谢对这个主题的启示。谢谢!

编辑:

阐明了确切发生的事情,简化:我在主文件中运行以下代码:

int a = 2000;
int b = .498*2000;
int c = .498*a;
std::cout << a << " " << b << " " << c << std::endl;

导致以下输出:

2000 996 995

我不明白的是为什么C和B根据2000是字面变量还是整数变量是不同的值。在我看来,在任何一种情况下都应应用相同的圆形或截断。谢谢。

我正在编译以下内容:

g++ -o main.o -g -std=c++0x

我认为差异来自编译时间评估与浮点表达式的运行时间评估。

编译器能够在编译时评估d。它仅在运行时评估g。但是,它们不需要导致完全相同的值。

从5.19常数表达式/4:

尽管在某些情况下必须在程序翻译过程中评估常数表达式,但可以在程序执行过程中评估其他表达式。由于该国际标准对浮点操作的准确性没有任何限制(在执行程序中。

最好避免使用此类代码。该标准不能保证此类数字的准确性。结果可能从编译器到编译器各不相同。它们可能会随着相同的编译器而变化,但优化标志不同。