移位操作的疑问

如下一段代码:

#ifndef MAGICTYPE
#define MAGICTYPE(FIRST, SECOND) ((FIRST << 16) + SECOND)
#endif
long getmagictype(unsigned short first, unsigned short second) {
        long msgtype = MAGICTYPE(first, second);
        return msgtype;
}

a、(FIRST << 16),这里不会溢出吗?

b、(FIRST << 16) + SECOND 两个unsigned short相加,不需要考虑溢出吗?

我第一反应是第二个问题不存在,因为c++对+操作符有一个规则,如果操作数类型长度大于int,则提升为操作数的类型进行+操作。

如果操作数类型长度小于+操作符,那么会被提升为int进行+操作。可以测试一下:

#include <stdio.h>

#ifndef MAGICTYPE
#define MAGICTYPE(FIRST, SECOND) ((FIRST << 16) + SECOND)
#endif
int main() {

        printf("signed short int length : %d\n", sizeof(signed short int));
        unsigned short int first = ((1<<16) - 1);
        unsigned short int second = 2;
        long msgtype = 0;

        printf("first   is : %x\n", first, first);
        printf("second  is : %x\n", second, second);
        msgtype = first + second;
        printf("msgtype is : %lx\n", msgtype, msgtype);
        return 0;
}

结果如下:

signed short int length : 2
first   is : ffff
second  is : 2
msgtype is : 10001

关于第一个问题,我测试了几个场景:

第一种情况:

#include <stdio.h>
#include <iostream>

#ifndef MAGICTYPE
#define MAGICTYPE(FIRST, SECOND) ((FIRST << 16) + SECOND)
#endif
int main() {
        unsigned int a=32;
        int k = 31;
        printf("((unsigned int)(1)<<32)-1 : %lu\n", ((unsigned int)(1)<<32)-1);
        printf("((unsigned int)(1)<<a)-1 : %lu\n", ((unsigned int)(1)<<a)-1);
        printf("((1)<<a) : %lx\n", ((1)<<a));
        return 0;
}

结果:

((unsigned int)(1)<<32)-1 : 4294967295
((unsigned int)(1)<<a)-1 : 0
((1)<<a) : 1

有这样的推测:

  a、((unsigned int)(1)<<32)-1 : 4294967295的结果是编译器把(1)<<32转换成unsigned int 0了,再进行减一。也就是(unsigned int)-1了,结果如上

  b、((unsigned int)(1)<<a)-1 : 0中(1)<<a的结果是在运行时计算了,这涉及到移位操作!1<<32对于整形变量已经溢出了,所以这里的操作结果和机器强相关。

    根据已经输出的结果可以推测,测试环境机器<<32之后溢出进行循环移位。操作结果又回到了1.最终操作结果就是0了

  c、为了验证b操作中的推测,又写了c测试项来证明上述推测

第二种情况:

#include <stdio.h>
#include <iostream>

#ifndef MAGICTYPE
#define MAGICTYPE(FIRST, SECOND) ((FIRST << 16) + SECOND)
#endif
int main() {
        printf("unsigned short int length : %d\n", sizeof(signed short int));
        unsigned short int first = ((1<<16) - 1);
        unsigned short int second = 2;
        long msgtype = 0;

        printf("first   is : %x\n", first, first);
        printf("second  is : %x\n", second, second);
        msgtype = (first << 16);
        printf("msgtype is : %lx\n", msgtype, msgtype);
        msgtype = MAGICTYPE(first, second);
        printf("msgtype is : %lx\n", msgtype, msgtype);

        first = 1;
        second = ((1<<16) - 1);
        printf("first   is : %x\n", first, first);
        printf("second  is : %x\n", second, second);
        msgtype = MAGICTYPE(first, second);
        printf("msgtype is : %lx\n", msgtype, msgtype);
        return 0;
}

测试结果:

unsigned short int length : 2
first   is : ffff
second  is : 2
msgtype is : ffffffffffff0000
msgtype is : ffffffffffff0002
first   is : 1
second  is : ffff
msgtype is : 1ffff

msgtpye为何输出的不是ff000000呢,为何多出来这么多个ff?求解惑

posted @ 2016-05-13 14:25  一介莽夫  阅读(223)  评论(0编辑  收藏  举报