机器对移位运算的看法

1.先说一个运算口诀叫“左乘右除”,如k<<1==>k*2; k>>1==>k/2;

2.左移
先看左移运算,因为相对于右移较为简单;
x向左移动K位,会丢弃最高的K位,并在右端补K个0,移位运算是从左到右课结合的,所以x<<j<<k等价于(x<<j)<<k;

3.右移
而对于右移运算,x>>K,一般而言,机器支持俩种右移方式,逻辑右移和算术右移,逻辑右移在左端补K个0,而算术右移在左端补K个最高有效位的值,这种方式对于有符号的运算是非常有效的,

来看一个数据:
在这里插入图片描述

斜体的数值表示位刚填充的数值;可以看到除一个条目外,其余都是补0,唯一的不同是算术右移的【10010101】,因为操作数的最高位位1,所以补1;

但是C标准并未定义有符号数要使用那种运算方式,这就意味着任何假设一种或者另一种右移形式的代码都会影响到代码的可移植性,然而,所有的机器组合都对有符号数使用算术右移,并且程序员也会假设使用这种方式;另一方面,对于无符号数,右移必须是逻辑运算;

但是对于Java来说,就与明确的定义,x>>k,表示使用算术运算右移k,而逻辑运算表示为x>>>k;

还有一种情况是:当K值很大,已经超出了int类型的取值范围,这时应该怎么办?(在32位系统中)
其实C语言已经给这种情况做了规避,当移动K位时,移位指令只考虑位移量的低log2(K),当K为32时,相当于移位0,K位34时,相当于移位2;但是这种方法在C语言中时没有保证的,就是这种方式没有被C严格规定;

先来了解一下什么是位模式,后边会用到,
我们都知道,计算机内存里只能存储0和1俩种数字,这就需要把别的数据都转换成二进制数字,在根据计算机所能存储的容量来决定最小的存储单元进行存储,这是位模式的存储方式;所以可以将位模式理解为就是计算机存储不同数据的一种数据表示方法;

再来了解一个东西,数学术语中的双射,后边会用到;
是指一个函数( F() )有俩面,将数值x映射为数值y,就是y=F(x),对于y,有唯一一个数x使等式成立;这里的y和x反向操作也同样成立,这种方式理解为双射;
在这里插入图片描述
需要注意的是,不同的机器对long的取值范围有不同的规定;图中显示,负数的取值范围会比正数的大1,那么,为什么会这样?这时候会引伸出另外一个问题,负数怎么表示?

4.补码编码
计算机表示负数的方式就是补码,在这个定义中,将字的最高有效位解释为字权,用函数B2T(ω)表示,二进制转补码;公式:
在这里插入图片描述
ω为4时,也就是长度设为4,可以取到极值,
最小值是TMin(4) = B2T(4)([1000])= -2^3=-8;
最大值是TMax(4) = B2T(4)([0111]);

111转为10进制为7,这就是负数的取值范围为什么会比正数大1的理论基础:有一半的位模式(符号位设置为1的数)表示负数,而另一半(符号位设置为0的数)表示非负数。因为0是非负数,就意味着能表示的整数比负数少一个;

可以看出来B2T(ω)是一个长度从w的位模式到TMin(w)和TMax(w)之间数字的映射,同无符号表示一样,在可表示的取值范围内的每个数字都有唯一一个ω位的补码编码,这就导出了与无符号数相似的补码原理:补码编码的唯一性;

函数T2B(ω)作为B2T(ω)的反函数,对于每个数x,满足TMin(ω)<=x<=TMax(ω);
则T2Bω(x)是x的ω位模式;

C 语言允许无符号数和有符号数之间的转换,大多数系统遵循的原则是底层的位保持不变;在一台采用补码的机器上,当从无符号数转换成有符号数时,就是应用函数U2Tω,从有符号数转换成有符号数时,应用函数T2Uω;ω表示数据类型的位数;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Aaronpack

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值