<1>.在了解位移之前,先了解一下正数和负数的二进制表示形式以及关系:
举例15和-15:
15 的原码: 00000000 00000000 00000000 00001111
补码: 11111111 11111111 11111111 11110000
+1 =
-15的原码:11111111 11111111 11111111 11110001
负数的原码即为:正数的原码取反,再加1。
<2>位移操作:(只针对 int类型的数据有效,java中,一个int的长度始终是32位,也就是4个字节,它操作的都是该整数的二进制数).也可以作用于以下类型,即 byte,short,char,long(当然,它们都是整数形式)。当为这四种类型是,JVM先把它们转换成int型再进行操作。
<< 左移
>> 右移
>>> 无符号右移
<< 和>>为数值位移,>>>为逻辑位移。【注】:Java中不存在<<<。
$1> m<<n的含义:把整数m表示的二进制数左移n位,高位移出n位都舍弃,低位补0. (此时将会出现正数变成负数的形式)
实例:
3<<2剖析:
3二进制形式: 00000000 00000000 00000000 00000011,按照$1的原理,得到00000000 00000000 00000000 00001100,即为12.
左移使整数变为负数:
10737418<<8
10737418二进制表示形式:00000000 10100011 11010111 00001010,按照$1的原理,得到10100011 11010111 00001010 00000000,即为:-1546188288.
$2> m>>n的含义:把整数m表示的二进制数右移n位,m为正数,高位全部补0;m为负数,高位全部补1.
实 例:
3>>2剖析:
3二进制形式: 00000000 00000000 00000000 00000011,按照$2的原理,得到00000000 00000000 00000000 00000000,即为0.
-3>>2剖析:
-3二进制形式: 11111111 11111111 11111111 11111101,按照$2的原理,得到11111111 11111111 11111111 11111111,即为-1.
以上:每 个整数表示的二进制都是32位的,如果右移32位和右移0位的效果是一样的。依次类推,右移32的倍数位都一样。
备注:对于右移32位与右移0位是结果是一样的,我一直不能够理解。现在我只能理解为32比较特殊。相当于整体全移。与移0位相同。左移也是一样的。
$3> m>>>n:整数m表示的二进制右移n位,不论正负数,高位都补零。
实例:
3>>>2剖析:
3二进制形式: 00000000 00000000 00000000 00000011,按照$3的原理,得到00000000 00000000 00000000 00000000,即为0.
-3>>>2剖析:
-3二进制形式: 11111111 11111111 11111111 11111101,按照$3的原理,得到00111111 11111111 11111111 11111111,即为1073741823.
【注】:对于$1,$2,$3,如果n为负数:这时JVM会先让n对32取模,变成一个绝对值小于32的负数,然后再加上32,直到 n 变成一个正数。
实例:
4<<-10
4的二进制形式:00000000 00000000 00000000 00000100,-10对32取模再加上32,不用说了,得到22,则4<<-10,即相当于4<<22。
此时按照再按照$1原理,得到00000001 00000000 00000000 00000000,得到的即为:16777216。
OK, 大功告成。
综上所述:
m<<n即在数字没有溢出的前提下,对于正数和负数,左移n位都相当于m乘以2的n次方.
m>>n即相当于m除以2的n次方,得到的为整数时,即为结果。如果结果为小数,此时会出现两种情况:(1)如果m为正数,得到的商会无条件 的舍弃小数位;(2)如果m为负数,舍弃小数部分,然后把整数部分加+1得到位移后的值。
---------------------------------------------------------------------------------
接 下来在此说说位操作的好处,速度超快,这些都是底层的二进制机器操作指令。
比如:a*2,
1.jvm先为变量a分配空间;
2.再进行a*2的操作;
3.再把结果返回给相应的变量。
而 a<<1,和a*2一样,它只需要一条指令即可,速度很快。当然前三种位移操作都是对2的倍数
进行操作时可用。
再 进行些许补充,谈到位操作,当然还要说到四个操作符:~(按位非),|(按位或),&(按位
与),^(按位异或),这些都是大学 计算机基础用法,对整数的二进制形式进行操作,然后再
转换为整数,具体操作如下。
1.~(按位非):【解义】对该整数的二进制形 式逐位取反。
~4:(一元操作符)
4的二进制形式为:00000000 00000000 00000000 00000100,逐位取反后得
到:11111111 11111111 11111111 11111011,即为-5.
2.| (按位或):【解义】对两个整数的二进制形式逐位进行逻辑或运算,原理为:1|0=1,0|0=0,1|1=1,0|1=1
等。
4|-5:
4的二进制形式为:00000000 00000000 00000000 00000100,
-5的二进制形式为:11111111 11111111 11111111 11111011,
逐位进行逻辑或运算:11111111 11111111 11111111 11111111,即得到-1.
3.&(按位与):【解义】对两个整数的二进制形式逐位进行逻辑与 运算,原理:1|0=0,0|0=0,1&1=1;0&1=0等。
4&-5:
4的二进制形式为:00000000 00000000 00000000 00000100,
-5的二进制形式为:11111111 11111111 11111111 11111011,
逐位进行逻辑与运算:00000000 00000000 00000000 00000000,即得到0.
实际应用:可以把字节转换为整 数,-64&0xFF=192,也可以用八进制的形式,-64&0377=192、
其实0xFF和0377都表示的是整数255、
4.^(按 位异或):【解义】对两个整数的二进制形式逐位进行逻辑异或运算,原理:1^1=0,1^0=1,0^1=1,0^0=0.
4^-5:
4的二进制形式为:00000000 00000000 00000000 00000100,
-5的二进制形式为:11111111 11111111 11111111 11111011,
逐位进行逻辑异或运算:11111111 11111111 11111111 11111111,即得到-1.
实际应用:按位异或可以比较两个数字是否相等,它利用 1^1=0,0^0=0的原理。 20^20==0
转自:http://aokunsang.javaeye.com/blog/615658
关于二进制一些说明:
关于负数的二进制表示方法
今天知道了对于负数的二进制方法的表示方法:例如 -5
第一步:首先要把5变成101的二进制形式
第二步:再者就是按位取反,(形 成前面全是1)010
第三步:在最后加1 形成:11111111 11111111 11111111 11111011
反过来如果把 最高位是1的二进制变成负的整形时
第一步:位取反,变成00000000 00000000 00000000 00000100
第二 步:在最低位加上1,形成101
第三步:形成整形5 ,在加上负号;
在java中怎么用代码实现二进制于十进制的转化
代码如下 | 复制代码 |
public int binaryInToInt(String str) { int j=0,i=0; char c; for(i=0;i<str.length();i++) { if(str.charAt(str.length()-i)=='1') { j=j+exp(2*ln(str.length()-i)); } } return j; } |
转自:
http://www.111cn.net
(1)正负表示方法用字节的最高位表示:"1"表示"正","0"表示"负"(2)计算机中数字是以哪个码储存的?补码(3) 负数 的二进制补码转换成十进制的方法1、把补码“取反”(把二进制数的各位“1”换“0”,“0”换“1”。比如“101010”取反后为“010101”)2、把取反后的二进制数“加1”3、最后用常规的方法把“加1”后的二进制数转换为十进制数 将负数转换为二进制
http://blog.111cn.net/onewalkingman/archive/2009/01/10/3746154.aspx
我们已经知道计算机中,所有数据最终都是使用二进制数表达。
我们也已经学会如何将一个10进制数如何转换为二进制数。
不过,我们仍然没有学习一个负数如何用二进制表达。
比如,假设有一 int 类型的数,值为5,那么,我们知道它在计算机中表示为:
00000000 00000000 00000000 00000101
5转换成二制是101,不过int类型的数占用4字节(32位),所以前面填了一堆0。
现在想知道,-5在计算机中如何表示?
在计算机中,负数以其正值的补码形式表达。
什么叫补码呢?这得从原码,反码说起。
原码:一个整数,按照绝对值大小转换成的二进制数,称为原码。
比如 00000000 00000000 00000000 00000101 是 5的 原码。
反码:将二进制数按位取反,所得的新二进制数称为原二进制数的反码。
取反操作指:原为1,得0;原为0,得1。(1变0; 0变1)
比如:将00000000 00000000 00000000 00000101每一位取反,得11111111 11111111 11111111 11111010。
称:11111111 11111111 11111111 11111010 是 00000000 00000000 00000000 00000101 的反码。
反码是相互的,所以也可称:
11111111 11111111 11111111 11111010 和 00000000 00000000 00000000 00000101 互为反码。
补码:反码加1称为补码。
也就是说,要得到一个数的补码,先得到反码,然后将反码加上1,所得数称为补码。
比如:00000000 00000000 00000000 00000101 的反码是:11111111 11111111 11111111 11111010。
那么,补码为:
11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 11111011
所以,-5 在计算机中表达为:11111111 11111111 11111111 11111011。转换为十六进制:0xFFFFFFFB。
再举一例,我们来看整数-1在计算机中如何表示。
假设这也是一个int类型,那么:
1、先取1的原码:00000000 00000000 00000000 0000000111111111 11111111 11111111 11111110
2、得反码: 11111111 11111111 11111111 11111110
3、得补码: 11111111 11111111 11111111 11111111
可见,-1在计算机里用二进制表达就是全1。16进制为:0xFFFFFF
个人总结:
补码:反码加1称为补码。
一个负二进制转为十进制
例如:11111111 11111111 11111111 11111110
第一步:减1 变为11111111 11111111 11111111 11111101(二进制,第一位不足时从第二位第一也为2)
第二步:取反 00000000 00000000 00000000 00000010
根据常用方法转为十进制.最后要加-号
关于java中的~按位非
如:~1
1二进制为 00000000 00000000 00000000 00000001
~1为: 11111111 11111111 11111111 11111110
首位为1说明此数为-根据上面的计算方法,即可以计算出结果