(九)二进制、位运算、位移运算符

JavaSE(九)

--二进制、位运算、位移运算符

一、二进制简介

现代电子计算机全部采用的是二进制,因为它只使用0,1两个数字符号,简单方便。数字电路中,1代表高电平,2代表低电平。这样,数据的传输通过控制电平的高低就可以了。计算机内部处理信息,都是采用二进制数来表示的。二进制(Binary)数用0和1的两个数字及其组合来表示任何数,进位规则是“逢二进一”,按从右至左的顺序,右低位,左高位。

二、二进制基础

1.所有的二进制数最高位代表符号位,0表示正数,1表示负数。

2.一个字节等于八位

3.正数的原码、反码、补码都一样。

4.一个数的原码就是根据数值和正负号直接写出来的码。

5.取反就是指0变1,1变0。

6.负数的反码=它的原码符号位不变,其他位取反;负数的原码=它的反码符号位不变,其他位取反。

7.负数的补码=它的反码+1;负数的反码=它的补码-1。

8.0的反码,补码都是0

9.Java没有无符号数,换言之,java中的数都是有符号的。

10.在计算机运算的时候,都是以补码的方式来运算的。存储数据也是以补码的方式来存储的

11.二进制与十进制的相互转换:

比如一个二进制数原码是:


0


0


0


0


0


1


0


1

先确定符号位,说明是正数。

再看数值,数值等于1x2^0+0x2^1+1^2^2=5(2^0代表2的0次方)

即每个第i位的数乘以2的i-1次方,再把这些全部加起来,就是10进制的数。

其实不仅二进制是这样算,所有进制的数(包括十进制)都是这么算的,比如78其实就是8x10^0+7x10^1。

十进制转为二进制就更简单了。

比如22,先用二的次方表示出来,即22=16+4+2=1x2^4+0x2^3+1x2^2+1x2^1+0x2^0;

显然,它的二进制表示就是


0


0


0


1


0


1


1


0

三、位运算

Java中有四个位运算,分别是“按位与&”、“按位或|”、“按位异或^”、“按位取反~”,这与逻辑运算符不同:

按位与&:两个全为1,结果为1.

按位或|:两个有一个为1,结果为1.

按位异或^:两个一个为1,一个为0,结果为1.

按位取反~:0变为1,1变为0.

注意:运算的时候均要先根据原码得到补码再进行位运算。

举例:

①~2=?

2的原码00000010,同样反码也是00000010,进行“~”的位运算,即取反,取反之后变成11111101,反码取反之后得到的结果也是反码,说明反码是11111101,显然是负数,负数的补码原码反码可不相等,要根据规律来,所以我们先减一算得反码是11111100,再符号位不变其他位取反算得原码10000011,这显然是-3。所以~2= -3。

②2&3=?

2=


0


0


0


0


0


0


1


0

3=


0


0


0


0


0


0


1


1

根据按位与的运算规则两个全为1结果才为1。那2&3的反码就是


0


0


0


0


0


0


1


0

这显然是正数,那反码原码一样,即原码也是00000010,显然是2.

所以2&3=2。

③2|3=?

同理

2=


0


0


0


0


0


0


1


0

3=


0


0


0


0


0


0


1


1

2|3=


0


0


0


0


0


0


1


1

显然答案是3,即2|3=3。

④~-5=?

-5原码是10000101,反码是11111010,补码是11111011.

算出补码,我们可以开始做按位取反运算了。

取反之后是00000100,这是一个正数,所以原码跟补码相同。

显然,答案就是4,即~-5=4.

⑤-3^3=?

先得出两个数的补码,3的补码显然是00000011。-3原码是10000011,反码是11111100,补码是11111101.


3


0


0


0


0


0


0


1


1


-3


1


1


1


1


1


1


0


1


3^3


1


1


1


1


1


1


1


0

11111110是补码,反码是11111101,原码是10000010.显然是-2。

即-3^3=-2.

⑥1-2=?

在二进制中,1-2会被认为1+(-2)。先算出各自补码,1的补码00000001,-2的原码10000010,-2的反码11111101,-2的补码11111110.


1


0


0


0


0


0


0


0


1


-2


1


1


1


1


1


1


1


0


1+(-2)


1


1


1


1


1


1


1


1

得到一个结果补码是11111111,那反码就是11111110,原码10000001,即-1,所以1-2=-1。

四、移位运算

Java中有三个移位运算:

算术右移”>>”:

所有位的码右移,符号位不变,低位溢出,并用符号位补溢出的高位

算术左移”<<”:

所有位的码左移,符号位不变,低位补0.

逻辑右移”>>>”:

所有位的码右移(包括符号位),低位溢出,高位补0.

注意:没有逻辑左移。使用”<<<”将会报错

例子:

①5>>2=?

5的补码为00000101


5


0


0


0


0


0


1


0


1


溢出位


5>>1(右移一位)


0


0


0


0


0


0


1


0


1


5>>2(右移两位)


0


0


0


0


0


0


0


1


0

得到的补码为00000001,显然原码也是00000001,即5>>2=1.

②-1>>2=?

-1的原码10000001,反码11111110,补码11111111


-1


1


1


1


1


1


1


1


1


溢出位


1>>1(右移一位)


1


1


1


1


1


1


1


1


1


1>>2(右移两位)


1


1


1


1


1


1


1


1


1

补码还是11111111,显然结果的补码跟原来一样,结果的原码也跟原来一样,即-1>>2=-1.

③-5<<2=?

-5原码10000101 反码11111010 补码11111011


-5


1


1


1


1


1


0


1


1


-5<<1(左移一位)


1


1


1


1


0


1


1


0


-5<<2(左移两位)


1


1


1


0


1


1


0


0

结果为补码为11101100,反码为11101011,原码为10010100,即-5<<2=-20

④127>>>2

127的补码01111111


127


0


1


1


1


1


1


1


1


127>>>1(右移一位)


0


0


1


1


1


1


1


1


127>>>2(右移两位)


0


0


0


1


1


1


1


1

显然127>>>2=31.

五、

在java中,如何最快判断一个数是不是2^的n次方呢?如何让一个数最快的变成它的两倍呢?

都是进行位运算,位运算是直接在内存中进行的,是最快的。

1.

public static boolean isPowerOfTow(int val){

return (val&-val)==val;

}

2.

时间: 2024-10-19 05:45:21

(九)二进制、位运算、位移运算符的相关文章

C 碎片九 预处理&amp;位运算&amp;文件

一.预处理 ////用宏 定义 两个带参数的宏  求 两个数的较大值 和 较小值 #define max(a,b) a>b?a:b #define min(a,b) a<b?a:b //宏定义 必须要在同一行 //打印出最大值 #define max2(a,b) if(a>b){\ printf("%d\n",a);\ }else{\ printf("%d\n",b);\ } // '\'在预处理阶段表示 连接符  把下一行代码和当前行连接成同一行

2015小米暑期实习笔试题_懂二进制(位运算)

总共3道题,最后一道还没AC出来... 世界上有10种人,一种懂二进制,一种不懂. 那么你知道两个int32整数m和n的二进制表达,有多少个位(bit)不同么? 输入例子: 1999 2299 输出例子: 7 此题解法类似于<编程之美>上面看到的某题 代码: #include <iostream> using namespace std; int countBitDiff(int m, int n) { int sum=0; for(int i=0;i<32;i++) if(

基础位运算基本原理和应用

微信公众号 位运算是编程语言的基础,在看源码的时候会看到很多位运算代码,但是在项目代码中很少会看到位运算.因为应用代码中,有很多判断和计算都可以直接用数值的判断和计算完成,没有必要去用位运算,以至于这些基础的东西慢慢用的越来越少,慢慢也就忘了.导致的一个结果就是看源代码很费力,因为大量的位运算逻辑,看不懂.作为程序员感觉数据位运算是非常必要,有点如下: 看源码时能够更好的理解 位运算更接近计算机的习惯,执行的效率会更高 装逼利器,在项目中使用位运算,体现逼格 N种基本的位运算 位运算 -- 与运

5/30 c语言中的位运算

1.什么是位运算? 位运算是指按二进制位进行的运算.因为在系统软件中,常要处理二进制的问题.储存单元中的各二进制位左移或者右移一位,两个数按位相加等.c语言灵活,接近底层,对程序员的要求高,不像其他语言对c语言进行了封装,出错性会高很多. 2.位运算符和位运算. 运算符&按位与  ~取反 |按位或    <<左移  ^按位或   >>右移.位运算中除了~以外,均为二元元运算符,即要求两侧各有一个运算量. 3.与&的应用. 清零,无论任何一个二进制的书与上一个0000

php位运算与二进制

?  二进制 二进制就是用0和1来表示计算机语言的,0,1可以表示任意数,其逢二进一 二进制有三个重要概念 ?位运算 位运算符运算规则: 按位与&:两位全为1,结果为1 按位或|:两位有一个为1,结果为1 按位异或^:两位中一个为0,一个为1,结果为1 按位取反~:0取1,1取0 根据规则, 计算一个数的步骤: 例如计算:~2=? 1.找出2的补码,[因为计算机运算是以补码的方式来进行运算的] 2的原码:00000000 00000000 00000000 00000010 //上面的字串从左往

Java千百问_03基本的语法(005)_二进制是如何做位运算的

点击进入_很多其它_Java千百问 二进制是如何做位运算的 程序中的全部数在计算机内存中都是以二进制的形式储存的.位运算说白了,就是直接对整数在内存中的二进制位进行操作. 其它运算符看这里:java种的运算符都有哪些 大部分运算流程都是先将整数转换为二进制.然后进行对应二进制操作.常见的操作有例如以下几种:以下我们具体说明,运算符的优先级看这里:java运算符的优先级是如何的 1.按位与 and两个二进制数进行按位与操作:同样位的两个数字都为1.则为1:若有一个不为1,则为0. 比如:00101

二进制-高效位运算

数独 数独是介绍位运算的好例子,运用位运算和不运用效率差别还是挺大的.我们先看数独需求: 1.当前数字所在行数字均含1-9,不重复 2.当前数字所在列数字均含1-9,不重复 3.当前数字所在宫(即3x3的大格)数字均含1-9,不重复(宫,如下图每个粗线内是一个宫) . 常规算法 若是我们采用常规方式的,每填写一个数字,需要检查当前行.列,宫中其他位置是否有重复数字,极端情况下需要循环27(3*9)次来进行检查,我们看下常规算法下check int check(int sp) { // 檢查同行.

&lt;13&gt;【了解】计算机中的进制+【理解】原码反码补码基本概念+【理解】为什么要引入反码、补码?+【掌握】位运算符介绍及使用+位运算应用:编程实现10进制转2进制

1 #include <stdio.h> 2 3 int main(int argc, const char * argv[]) { 4 5 //定义10进制数,打印出10.8.16进制的值 6 int a = 13; 7 printf("%d\n",a); 8 printf("%o\n",a); 9 printf("%x\n",a); 10 11 //int 64 4个字节 12 int b = 0b0000000000000000

java二进制,原码、反码、补码、位运算

1.二进制计数法的概念 人们在日常生活中和生产实践中,我们接触到越来越多的数字,创造了分组计数的制度.而我们的生活中,一般采用了"满十进一"的十进制计数法, 我们现在已经熟悉并经常运用这一种计数法了.但也有采用其他计数法.如二进制,六进制,十六进制等计数法.现在就来讲一讲"二进制"和"十进制"的关系 2.十进制和二进制数的互化 (1)化十进制数为二进制数 <1>比较小的十进制数为二进制数可以用观察法. 例:化45为二进制数 因为2的0