【发布时间】:2018-02-16 21:24:32
【问题描述】:
考虑以下 c++ 代码:
int main()
{
int a = -3 >> 1;
int b = -3 / 2;
cout << "a = " << a << ", b = " << b << endl;
return 0;
}
执行时,此代码给出以下结果:
a = -2, b = -1
我有点困惑,因为我认为这两个操作在编译的 exe 中产生了相同的代码,即:
shr ax, 1
但似乎情况并非如此(我用 2 个不同的编译器进行了测试)。有人可以向我解释为什么这些操作不会产生相同的结果?
---- 编辑于 17.02.2018 ----
好吧,我知道这是一个新手问题,即使我不是真正的 C++ 初学者
事实上,当我对一个值应用右移(即 shr 或 >> 运算符)时,我完全理解二进制会发生什么。 这不是我的问题。
相反,我的问题是关于对值应用二进制移位或对值进行除法之间的区别。 我预计结果是一样的,因为直到现在我都假设编译器在编译期间用适当的 shr/shl 指令替换除以 2 或乘以 2,作为优化.假设两条指令生成的二进制文件应该相同,那么结果也应该相同。
但显然不是这样。出于这个原因,我很高兴知道编译器编译这两条指令(分析助记符并不是我的强项)的底层发生了什么,它们有什么区别,最后,这个应该让我理解为什么结果在数学方面有所不同。
作为一个具体案例,我在试图简化的图形应用程序的源代码中遇到了这个问题。为了便于人类阅读代码,我将一些代码如“(widthB - widthA) >> 1”替换为“(widthB - widthA) / 2”。但是这样做引入了一个错误:几个图形项目不再像预期的那样居中。从中我注意到,如果除法的值为负,则用除法替换移位会产生不同的结果,这就是上述问题的原因。
我希望这能解决问题。
【问题讨论】:
-
首先,打消你脑中C++是根据CPU操作定义的观念
-
我不清楚哪一部分让你感到困惑。你不明白为什么
-3 >> 1产生-2,或者为什么-3 / 2产生-1? -
关于您的编辑,我认为您错过了一个非常基本的方面:并不是它们产生不同的结果,因为它们的编译方式不同。那是倒退。它们的编译方式不同,因为它们应该产生不同的结果(部分是因为标准是这样说的,部分是因为它依赖于实现并且实现是这样说的)。
-3 >> 1应该产生-2,-3 / 2应该产生-1,如果它们应该产生不同的结果,显然需要不同的指令。 -
thx hvd,您的评论回答了我的问题。这正是我想知道的。
标签: c++ operators difference integer-division