最近老是在二进制数制上举棋不定,花了1上午时间翻阅资料,记录下来!!

先列几个概念:

[b]1、原码:[/b]

[b][color=red]原码表示法是机器数的一种简单的表示法。其符号位用0表示正号,用1表示负号,数值一般用二进制形式表示。[/color][/b]数值有正负之分,计算机就用一个数的最高位存放符号(0为正,1为负).这就是机器数的原码了.假设机器能处理的位数为8.即字长为1byte,原码能表示数值的范围为:(-127~-0 +0~127)共256个


例:
7的原码:0000 0111
-7的原码:1000 0111

7+(-7): 0000 0111 + 1000 0111 = 1000 1000 = 120(显然不对)

所以引入了 [b]2、反码 :[/b]

[color=red][b]反码可由原码得到。如果机器数是正数,则该机器数的反码与原码一样;如果机器数是负数,则该机器数的反码是对它的原码(符号位除外)各位取反而得到的。反码的取值空间和原码相同且一一对应。[/b][/color]

例:
5的原码:0000 0101
-7的反码:1111 1000(原码:1000 0111 除符号位按位取反)

5+(-7): 0000 0101 + 1111 1000 = 1111 1101(反) = 10000010(原) = -2 (正确)

1+(-1):0000 0001 + 111111110 = 1111 1111 = -0 (错误)

问题出现在(+0)和(-0)上,在人们的计算概念中零是没有正负之分的.(印度人首先将零作为标记并放入运算之中,包含有零号的印度数学和十进制计数对人类文明的贡献极大).

于是就引入了[b]3、补码: [/b]

[b][color=red]负数的补码就是对反码加一,而正数不变,正数的原码反码补码是一样的.在补码中用(-128)代替了(-0),所以补码的表示范围为:(-128~0~127)共256个。[/color]

[color=blue]注意:

1.(-128)没有相对应的原码和反码, (-128) = (10000000)

2.正数的补码、反码都和原码一样

[/color][/b]

4、关于右移(>>)和无符号右移(>>>)

	byte b = (byte) 0xf1;
byte c = (byte) (b >> 4);// 有符号右移
byte d = (byte) (b >>> 4);// 无符号右移(即高位自动填充0)
byte e = (byte) ((b & 0xff) >> 4);
System.out.println(b);
System.out.println(c);
System.out.println(d);
System.out.println(e);


结果:
-15
-1
-1
15


为什么c和d的结果是一样的,而e却实现了无符号右移?

首先,在执行b>>4或b>>>4操作时jvm都会先将b转为int型:

1111 1111,1111 1111,1111 1111,1111 0001

>>4 : 1111 1111,1111 1111,1111 1111,1111 1111
>>>4: 0000 1111,1111 1111,1111 1111,1111 1111

转为byte时,截取后8位:1111 1111 其为 -1 的补码。

而先执行了(b & 0xff)操作之后其转为int的二进制:

0000 0000,0000 0000,0000 0000,1111 0001

>>4: 0000 0000,0000 0000,0000 0000,0000 1111

转byte: 0000 1111 故结果为:15

[color=red][b]移位操作特别注意:比如int型右移x位, 实际上执行的操作时 x=x%32,所以右移32位实际上是右移了0位!![/b][/color]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值