1.位权
数制中每一固定位置对应的单位值,也就是某一位上的“1”所表示的数值的大小,称为该位的位权.
比如10进制数:1234
个位位权1*10^0=1;
十位位权1*10^1=10;
千位位权1*10^3=1000.
2. 二进制和十进制的转换
比如67这个数
十进制转换成二进制 采用短除2法;
除 | 商 | 余数 |
---|---|---|
2\67 | 33 | 1 |
2\33 | 16 | 1 |
2\16 | 8 | 0 |
2\8 | 4 | 0 |
2\4 | 2 | 0 |
2\2 | 1 | 0 |
1\2 | 0 | 1 |
商是0的时结束,将余数从下往上数,即可得到二进制数结果 1000011
二进制转换成十进制 采用科学计数法,按位权展开;
比如上面这个数1000011
1*2^(1-1)+1*2^(2-1)+1*2^(7-1)=1+2+64=67;
3.二进制的位运算
1,先介绍介个基本的概念原码,反码,补码;
原码: 一个整数按照绝对值大小转换成二进制数称为原码
比如 00000000 00000000 00000000 00001000是8的原码
反码: 将二进制数按位取反,所得二进制数称为原二进制数的反码
比如将 00000000 00000000 00000000 00001000 取反
得到反码 11111111 11111111 11111111 11110111
补码: 反码加1称为补码
11111111 11111111 11111111 11110111+1=
11111111 11111111 11111111 11111000(二进制逢2进1)
2,负数以其正值的补码形式表示
在二进制里面(32位,其中最高位为0表示的是正数,最高位为1表示的是负数)
其中0含义代表的是false,1含义表示true
在接触位运算符的时候,把1想成true,把0想成false,结果为true代表1,结果为false代表0,
感觉是不是和java逻辑运算符差不多!
&运算
按位与运算 两位都为1,结果才是1;0&0=0;0&1=0;1&0=0;1&1=1
是不是可以理解成两个都为true,结果才是true
int a = 8;// 8(10)==00000000 00000000 00000000 00001000(2)
int b = 9;// 9(10)==00000000 00000000 00000000 00001001(2)
int c = a & b;// == 00000000 00000000 00000000 00001000(2)
System.out.println(c);// c=8
按位与运算的应用:
可以判断一个数x的奇偶性(x&1=0,说明x是偶数,x&1=1,说明x是奇数)
System.out.println(a & 1);// 结果0,说明a是偶数
System.out.println(b & 1);// 结果1,说明b是奇数
保留指定的位数,比如想保留数a的后8位(0xff是16进制,转换二进制00000000 00000000 11111111 1111111)
System.out.println(a = a & 0xff);// ==00000000 00000000 00000000 00001000(2)
System.out.println(Integer.toBinaryString(a & 0xff));
| 或运算
按位或 只要有一个为1,结果就为1;0|0=0;0|1=1;1|0=1;1|1=1
是不是可以理解成两个中有一个为true,结果就是true
int a = 8;// 8(10)==00000000 00000000 00000000 00001000(2)
int b = 9;// 9(10)==00000000 00000000 00000000 00001001(2)
int c = a | b;// == 00000000 00000000 00000000 00001001(2)
System.out.println(c);// c=9
按位或运算的应用;
将一个数x指定位全部换成1
比如上面的a
//数a的后8位全部变成1
System.out.println(a = a | 0xff);//== 00000000 00000000 00000000 11111111(2)
System.out.println(Integer.toBinaryString(a | 0xff));
^ 异或运算
按位异或运算 相应位值不同,则该位结果为1,否则为0;0^0=0;0^1=1;1^0=1;1^1=0
是不是可以理解成两个都不为true或者false时,结果才是true
int a = 8;// 8(10)==00000000 00000000 00000000 00001000(2)
int b = 9;// 9(10)==00000000 00000000 00000000 00001001(2)
int c = a ^ b;// == 00000000 00000000 00000000 00000001(2)
System.out.println(c);// c=1
按位异或的应用:
定位反转 将一个数x的0位变成1,1位变成0
System.out.println(a ^ 0xff);// == 00000000 00000000 00000000 11110111(2)
System.out.println(Integer.toBinaryString(a ^ 0xff));
交换a和b的数值
a = a ^ b;
b = b ^ a;
a = a ^ b;
System.out.println(a);// 9
System.out.println(b);// 8
~ 反码
按位取反 将一个位上的数按位取反,即0变成1,1变成0;~1=0 ;~0=1;
是不是可以理解成!true,结果是false,!false,结果是true.
先了解一下下面负数二进制表示形式;上面说了,负数以其正值的补码形式表示
int a = 8;// 8(10)==00000000 00000000 00000000 00001000(2)
a = ~a;
//运算过程
// 原码 00000000 00000000 00000000 00001000(2)
// 取反 11111111 11111111 11111111 11110111(2) 是个负数
// 减一 11111111 11111111 11111111 11110110(2) 得到了负数绝对值的反码
// 取反 00000000 00000000 00000000 00001001(2) 的到了负数的绝对值
//转换十进制 等于 9,所以a=-9;
System.out.println(a);//-9
负数以其正值的补码形式表示,补码等于负数绝对值的反码+1
<< 左移
将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)
int a = 8;// 8(10)== 00000000 00000000 00000000 00001000(2)
int b = -8;// -8(10)=11111111 11111111 11111111 11111000(2)
System.out.println(a << 1);// 00000000 00000000 00000000 00010000(2)==16(10)
System.out.println(b << 1);// 11111111 11111111 11111111 11110000(2)==-16(10)
左移的规律:
一个数y左移n位(y<< n),就相当于这个数乘以2^n;
>>右移
将一个运算对象的各个二进制位全部右移若干位(是正数,左边的二进制位补0,是负数,左边二进制位补1;右边统统舍弃)
int a = 8;// 8(10)== 00000000 00000000 00000000 00001000(2)
int b = -8;// -8(10)=11111111 11111111 11111111 11111000(2)
System.out.println(a >> 1);// 00000000 00000000 00000000 00000100(2)==16(4)
System.out.println(b >> 1);// 11111111 11111111 11111111 11111100(2)==-16(4)
右移的规律:
一个数y右移n位(y>> n),就相当于这个数除以2^n;
>>>无符号右移
各个位向右移指定的位数,右移后左边空出的位用零来填充,移除右边的位被舍弃
int a = 8;// 8(10)== 00000000 00000000 00000000 00001000(2)
int b = -8;// -(10)=11111111 11111111 11111111 11111000(2)
System.out.println(a >>> 1);// 00000000 00000000 00000000 00000100(2)==4(4)
System.out.println(b >>> 1);// 01111111 11111111 11111111 11111100(2)==2147483644(4)