内容简介:前言我们都知道,在计算机世界里,再复杂,再美的程序,到最后都会变成0与1。也就是我们常说的:二进制。二进制相信大家都很熟悉。与现实世界不同的是,在现实世界里,我们通常都是用十进制来表示的,也就是遇十进一,这些都是我们熟悉的。到这里,我们就会发现端倪,现实世界中的十进制与计算机中的二进制其计量单元是不一样的。那它们之间怎么转换呢?这就涉及到一些比较基础的计算机知识。不在本文中讨论(如果有兴趣,可以在下次讲讲)。嗯,回到今天的主题,来说说位运算,这又是一个怎样的概念呢?我们从小就开始接触,现实世界中的加减乘除这
本文首发于个人微信公众号《andyqian》,期待你的关注
前言
我们都知道,在计算机世界里,再复杂,再美的程序,到最后都会变成0与1。也就是我们常说的:二进制。二进制相信大家都很熟悉。与现实世界不同的是,在现实世界里,我们通常都是用十进制来表示的,也就是遇十进一,这些都是我们熟悉的。到这里,我们就会发现端倪,现实世界中的十进制与计算机中的二进制其计量单元是不一样的。那它们之间怎么转换呢?这就涉及到一些比较基础的计算机知识。不在本文中讨论(如果有兴趣,可以在下次讲讲)。嗯,回到今天的主题,来说说位运算,这又是一个怎样的概念呢?我们从小就开始接触,现实世界中的加减乘除这些运算,也就是十进制中的运算。今天我们要说的是:二进制位中的一些常用运算。例如:& (位与),| (位或) ,^(异或),<<(左移),>>(右移) 等等。
真与假
在进行运算符使用之前,我们有必要说下真假。在 Java 中,我们都知道,用 true 值表示真,false 值表示假。其实在计算机中,通常使用 1 表示真,0表示假。使用过Json的同学应该知道,Java中的boolean类型,用1也是可以反序列化成true,0反序列化为false的。
& (位与)
在说位与之前,我们先来说说我们熟悉的 && 逻辑与操作。简单来说: A&&B 也就是:A且B同时成立时为真,否则为假。也有人称之为:“一假必假”。
现在我们再来看位与。首先,我们来看一段程序:
@Test
public void testBit(){
int a = 8;
int b = 9;
System.out.println("a binary: "+Integer.toBinaryString(a));
System.out.println("b binary: "+Integer.toBinaryString(b));
System.out.println("a & b binary: "+Integer.toBinaryString(a&b));
System.out.println("a & b result: "+(a&b));
}
再看解释之前,我们先猜猜结果是多少?
代码解释:
位与:我们从字面意思上来理解,也是二进制位的与操作。
数字 8 的十进制是: 1000 。
数字 9 的十进制是: 1001。
我们再来进行位于操作:
如下所示:
8:1000
9:1001
&
8 1000
最左边的 1&1 = 1,中间的 0&0 = 0,最右边的0&1 = 0。
二进制的结果为:1000,转换为10进制后为 8。
程序运行结果如下:
a binary: 1000
b binary: 1001
a & b binary: 1000
a & b result: 8
结果是符合预期的。
| (位或)
上面说 & (位与) 操作,现在我们来看看位或操作,继续使用上面的例子:如下所示:
@Test
public void testBit(){
int a = 8;
int b = 9;
System.out.println("a binary: "+Integer.toBinaryString(a));
System.out.println("b binary: "+Integer.toBinaryString(b));
System.out.println("a & b binary: "+Integer.toBinaryString(a|b));
System.out.println("a & b result: "+(a|b));
}
再看看二进制:
8:1000
9:1001
|
9 1001
最左边的 1|1 = 1,中间的0|0 = 0 ,最右边的 0|1 = 1。
结果二进制为: 1001 对应的10进制为 9。
运算结果如下:
a binary: 1000
b binary: 1001
a & b binary: 1001
a & b result: 9
^(异或)
这个运算符比较有意思,异从字面上来理解是:不同的。放在位操作里也是一样的。继续使用上面的例子:
@Test
public void testBit(){
int a = 8;
int b = 9;
System.out.println("a binary: "+Integer.toBinaryString(a));
System.out.println("b binary: "+Integer.toBinaryString(b));
System.out.println("a & b binary: "+Integer.toBinaryString(a^b));
System.out.println("a & b result: "+(a^b));
}
继续看二进制:
8:1000
9:1001
^
1 0001
位相同时取假,不同时取真。左边的 1=1 相同取假,也就是0。中间的0=0 也为假为0。最右边的0不等于1,为真。结果也就为1。
<<(左移)
在现实世界里,我们经常使用乘法。<< 则表示二进制中的位移操作,低位补0。例如:8<<1。
@Test
public void testCode(){
int a =8;
System.out.println("a toBinaryString: "+Integer.toBinaryString(a));
System.out.println("a<<1 toBinaryString: "+Integer.toBinaryString(a<<1));
System.out.println("result: "+(a<<1));
二进制如下:
8 1000
8<<1
16 10000
结果为: 2^4 = 16。 << 左边 a 表示基数, 右边 1 则表示需要位移动的位数。 箭头指向哪边,则向哪边位移。程序运行结果:
a toBiryString: 1000
a<<1 toBinaryString: 10000
result: 16
>> 右移
(右移) 与左移 << 则是相反的,高位补0 。继续上面的例子:
@Test
public void testCode(){
int a =8;
System.out.println("a toBinaryString: "+Integer.toBinaryString(a));
System.out.println("1>>a toBinaryString: "+Integer.toBinaryString(a>>1));
System.out.println("result: "+(a>>1)
}
二进制:
8 : 1000
8>>1
4 : 0100
运行结果:
a toBinaryString: 1000
a>>1 toBinaryString: 100
result: 4
其实这里还有一个比较好记的口诀:
a>>n 则表示: a / (2^n) 次方。 (取整)
a<<n 则结果为: a * (2^n) 次方。
现在我们来速算一下:
当a = 13, n = 2 时。13<<2 等于 13* 4 = 52 。 13/4 = 3。
(上述速算法,如有错误,欢迎打脸!!!)
我们在源码以及常见算法中位移运算是非常常见的,一位Java程序员掌握位运算也是很有必要的。这对我们算法,源码理解都非常有帮助!
相关阅读:
《上千行存储过程有感!》
《软件之路》
《浅谈 Java JPDA》
《说说 MySQL 权限》
<center> </center>
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Zen of CSS Design
Dave Shea、Molly E. Holzschlag / Peachpit Press / 2005-2-27 / USD 44.99
Proving once and for all that standards-compliant design does not equal dull design, this inspiring tome uses examples from the landmark CSS Zen Garden site as the foundation for discussions on how to......一起来看看 《The Zen of CSS Design》 这本书的介绍吧!