关于C ++二进制的东西

时间:2012-07-31 14:57:15

标签: c++

#include <iostream>

using namespace std;

int main()
{
    for(int i=63;i>=0;--i)
    {
        cout<<(((1<<63)+1)&(/*(long long)*/1<<i)?"1":"0");
    }

    return 0;
}

结果如下:00000000000000000000000000000001000000000000000000000000000000000001

那么,谁能告诉我结果如何?

我问这个问题只是因为我正在阅读有关XDR错误的“CA-2002-25”。我现在想更多关于C Plus Plus中的溢出。

2 个答案:

答案 0 :(得分:3)

嗯,很难说出你真正期待的是什么,但是通过编译器运行它会产生许多有用的警告。如果你在整个地方添加长长的整数文字符号,如下所示:

#include <iostream>

using namespace std;

int main()
{
    long long num = 0x7fffffff00000000ULL >> 32;
    for(int i=63;i>=0;--i)
    {
        cout<<(((1ULL<<63)+1ULL)&(1ULL<<i)?"1":"0");
    }

    return 0;
}

你得到答案

1000000000000000000000000000000000000000000000000000000000000001

这是我期望你的循环做的事情。我不知道你期望num做什么,因为你没有使用这个值,但是嘿!我也装饰了它。

这会回答你的问题吗?

答案 1 :(得分:0)

试试这个:

#include <iostream>

int main()
{
    long long num=0x7fffffff00000000ll >> 32; 
                                //  ^^    
                                // Literals are by default int
                                // need to add ll to let the compiler
                                // know it is long long
    for(int i=63; i>=0 ;--i)
    {   
        long long mask = (1ll << i); 
                       //  ^^    Note here I want this to be a long long
                       //        before I start shifting it.
        std::cout << ((num & mask)?1:0);
    }   
    std::cout << "\n";

    return 0;
}

./a.out
0000000000000000000000000000000001111111111111111111111111111111

查看您的代码:

cout<<(((1<<63)+1)&(/*(long long)*/1<<i)?"1":"0");

那里有一个常数:

int val = (1<<63)+1;
// since these are all integer literals (and I am guessing your platform is 32 bit)
0x00000001  or 000000000000000000000000000000001

因此,当您使用该表达式的第二部分循环它时:

/*(long long)*/1<<i

在i&gt;之后32 结果未定义但看起来它正在包裹并重新开始。所以你要设置

10000000000000000000000000000000100000000000000000000000000000001
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^    Mask bit wrapped around
                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The mask on 0x00000001