左移 右移 逻辑右移 算术右移

来源:互联网 发布:日本搞笑综艺节目知乎 编辑:程序博客网 时间:2024/04/30 02:30
左移只有一种:

规则:丢弃最高位,往左移位,右边空出来的位置补0

右移有两种:
1. 逻辑右移:丢弃最低位,向右移位,左边空出来的位置补0

2. 算术右移:丢弃最低位,向右移位,左边空出来的位置补原来的符号位(即补最高位)

C语言标准:无符号数右移时执行的是逻辑右移,有符号数右移时执行的是算术右移

示例1

#include <iostream>using namespace std;void main(){int a = 1;unsigned int b = (a << 31) >> 31;cout<<"b = "<<b<<endl;getchar();}

上面程序的意思很简单,即有符号的整型a,先左移31位,再右移31位,最后把结果转成无符号数打印出来

整型a:         00000000 00000000 00000000 00000001

左移31位后:10000000 00000000 00000000 00000000 最右侧直接补0

右移31位后: 11111111   11111111   11111111   11111111  a是有符号数,采用算术右移,最左侧补符号位,即1


示例2

#include <iostream>using namespace std;void main(){unsigned int a = 1;unsigned int b = (a << 31) >> 31;cout<<"b = "<<b<<endl;getchar();}

与示例1相比区别在于,把有符号的整型a替换成了无符号型的,其他操作一样,同样是先左移31位,再右移31位,最后把结果转成无符号数打印出来

整型a:        00000000 00000000 00000000 00000001

左移31位后:10000000 00000000 00000000 00000000 最右侧直接补0

右移31位后:00000000 00000000 00000000 00000001 a是无符号数,采用逻辑右移,最左侧补0

执行结果如下:



注意:
移位时移动的位数千万不要超过数字原本占有的位数,比如int型的数字移位时不要超过31位,更不要移动数为负数,因为不同的编译器处理方式可能是不一样的,我们不应该写出这种不确定结果的程序
示例
#include <iostream>using namespace std;void main(){unsigned int a = 1;unsigned int b = a << 33;cout<<"b = "<<b<<endl;getchar();}
左移位数为33位,windows下,Visual Studio 2008的执行结果来看,会产生一条警告信息,“warning C4293: “<<”: Shift 计数为负或过大,其行为未定义”,实际操作为:用要求左移的位数去模该类型的最大位数,然后按余数进行移位,即实际移动位数为 33 % 32 = 1,即左移1位。同理推导出若左移32位时,实际操作为左移32 % 32 = 0,即不移动。至于左移位数为负时,我们就不再讨论了
上面程序的执行结果为:

经测试,在linux下,g++编译器执行的结果也是如此,即使这样,我们仍然不应该采用这种危险性的做法
右移时同理,移动的位数也不应超过数字占有的位数,更不应为负数
0 0
原创粉丝点击