理解Java中的byte
介绍
byte为一个字节,即8位二进制组成。在Java中,byte类型的数据是8位带符号的二进制数
我们知道,Java中,byte类型的取值范围为:[-128, 127]
byte取值范围分析
为什么不是-128到128呢?
- 运算规则
计算机中的数是以反码形式存储的,反码再求反码得到该数的真值
正数的最高位为0,正数的值就是二进制表示的值
负数的最高位都是1,负数的值是取反后加1,然后加个负号得到的值
比如: 00001110,最高位为0表示正数,则最后表达的十进制数为14
比如: 10000101,最高位为1表示负数,按位取反为11111010,加1,为:11111011,表示十进制数:2的6次方+2的5次方+2的4次方+2的3次方+2的1次方+2的0次方=64+32+16+8+2+1=123,则最后得到的真值为:-123
所以:最小的负数: 10000000,取反得到:11111111,加1得到:10000000,得到十进制数:128,加负号得到:-128
最大的负数:11111111,取反得到:10000000,加1得到:00000001,得到最后的负数:-1
最大的正数为:01111111,得到:2的7次方-1=127
下面的例子说明了进制转换的问题
public class Demo6 {
public static void main(String[] args) {
int a = 130; // 0b10000010
byte b = (byte) a; // 10000010取反:11111101加1得到:01111110,-126
System.out.println(b); // 结果:-126
int k = 780; // 0b1100001100
byte kb = (byte) k; // 因为byte是8位二进制,而int为32位二进制,超过8位的部分舍去了,保留最后8位
// 00001100===>12
System.out.println(kb); //结果:12
}
}
原码、反码、补码
原码:就是二进制码,最高位为符号位,0表示正数,1表示负数,剩余部分表示真值
反码:在原码的基础上,正数反码就是他本身,负数的反码为:负数除符号位之外全部按位取反。
补码:正数的补码就是自己本身,负数的补码是在自身反码的基础上加1
逻辑运算符
& :当2个都为1的时候为1, 其他都是0 。 1&1 = 1, 1&0 = 0, 0&0 = 0; 他的作用是清0
| : 当2个只要有一个为1,就是1. 1|0 = 1; 0|0 = 0, 1|1 = 1;
^: 相同为0, 不相同为1, 1^0 = 1, 1^1 = 0, 0^0 = 0; 他的作用是定位翻转。
~: 按位取反,0变为1, 1变为0;
移位操作符
包含: <<(左移一位*2) 、>>(右移一位/2) 、 >>>
<< 表示左移,不分正负数,丢去高位,低位补0,如果移动的位数大于32, 那么就需要取余(例如下方<<10等价于<<2)
正数 x = 30 << 2
30的二进制原码: 00011110
30的二进制补码: 00011110
向左移动两位: 01111000 低位补0,丢去高位
结果 x = 120 也可通过30*2*2得到
负数 y = -18 << 2
-18的二进制原码: 10010010
-18的二进制反码: 11101101
-18的二进制补码: 11101110
左移2位的补码: 10111000 低位补0,丢去高位
反码: 10110111 补码转反码,减1,
原码: 11001000 反码转原码,除高位按位取反
结果 y = -72 也可通过-18*2*2得到
>>表示右移,如果该数为正,则高位补0,若为负数,则高位补1
正数 x = 30 >> 2
30的二进制原码: 00011110
30的二进制补码: 00011110
向右移动两位: 00000111 高位补0,丢去低位
结果 x = 7 也可通过 30/2/2得到
负数 y = -18 >> 2
-18的二进制原码: 10010010
-18的二进制反码: 11101101
-18的二进制补码: 11101110
右移2位的补码: 11111011 高位补1,丢去低位
反码: 11111010 补码转反码,减1,
原码: 10000101 反码转原码,除高位按位取反
结果 y = -5 也可通过-18/2/2
>>>表示无符号右移,也叫逻辑右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0
以下的x,y为int型,即32位的二进制数
正数 x = 30 >>> 2 结果与 x = 30 >> 2 一致
负数 y = -18 >>> 2
原码: 10000000 00000000 00000000 00010010
反码: 11111111 11111111 11111111 11101101
补码: 11111111 11111111 11111111 11101110
右移: 00111111 11111111 11111111 11111011
结果: y = 1073741819
Java代码演示
byte kk = 30 << 2;
System.out.println(kk); // 结果:120
byte xx = -18 << 2;
System.out.println(xx); // 结果:-72
byte yy = 30 >> 2;
System.out.println(yy); // 结果:7
byte mm = -18 >> 2;
System.out.println(mm); // 结果:-5
int r3z = 30 >>> 2;
System.out.println(r3z); // 结果:7
int r3f = -18 >>> 2;
System.out.println(r3f); // 结果:1073741819