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

左移只有一种:

 

规则:丢弃最高位,往左移位,右边空出来的位置补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++编译器执行的结果也是如此,即使这样,我们仍然不应该采用这种危险性的做法

右移时同理,移动的位数也不应超过数字占有的位数,更不应为负数

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值