为什么“-3>> 1”不会产生与“-3 / 2”相同的结果?

时间:2018-02-16 21:24:32

标签: c++ operators difference integer-division

考虑以下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种不同的编译器进行了测试)。有人可以向我解释为什么这些操作不会产生相同的结果?

----编辑于18.02.2018 ----

嗯,我知道这是一个新手问题,即使我不是C ++的初学者

事实上,我完全理解当我对值应用右移(即shr或&gt;&gt;运算符)时二进制发生的情况。 这不是我的问题

相反,我的问题是关于对值应用二进制移位或对值进行除法之间的差异我预计结果是相同的,因为直到现在我假设编译器在编译期间用适当的shr / shl指令将除法替换为2或乘以2作为优化。假设生成的二进制文件对于两个指令都应该是相同的,所以结果也应该是相同的

显然并非如此。出于这个原因,我很高兴知道在编译器编译这两个指令(分析助记符不是我的强项)时会发生什么,他们的差异是什么,最后,这个应该让我理解为什么结果在数学术语上有所不同。

作为一个具体案例,我在一个图形应用程序的源代码中遇到了这个问题,我试图使其变得更简单。为了便于人类阅读代码,我更换了一些代码,如“(widthB - widthA)&gt;&gt; 1”by“(widthB - widthA)/ 2”。但这样做会引入一个错误:几个图形项目不再按预期集中。从那时我注意到,如果除法的值是负的,那么用一个除法取代转移会产生不同的结果,这就是上述问题的原因。

我希望这能解决问题。

2 个答案:

答案 0 :(得分:4)

二进制补充系统

-3

11111111111111111111111111111101       :BIN

右移时

11111111111111111111111111111110       :BIN

这意味着小数点为-2。

但是当你将-3 / 2这两个数字分开时,答案是-1.5,当把它转换为整数时,它就是-1。

答案 1 :(得分:0)

它与内部表示有符号和无符号数字的方式有关,如果你给这个代码一个镜头,你会看到它的行为符合预期。

#include <iostream>

using namespace std;

    int main()
    {
        unsigned int a = 3 >> 1;
        unsigned int b = 3 / 2;

        cout << "a = " << a << ", b = " << b << endl;
        return 0;
    }

我建议查找“twos compliment”