原码:十进制数据的二进制表现形式,最左边是符号位,0为正,1为负。
56 ==> 0 0111000
符号位 数据
最大值:01111111 ==> 127
最小值:11111111 ==> -127
00000001 ==> 1
00000010 ==> 2
利用原码对正数计算是不会有问题的。
10000000 ==> 0
我们对0 + 1,0+1=1
但1000000 + 1 为10000001 ,而10000001 ==> -1
在对负数进行运算时出现了错误,实际运算结果与预期结果是相反的。此时我们引入反码
反码:正数的反码是其本身,负数的反码是符号位保持不变,其余位取反。
计算规则:正数的反码不变,负数的反码在原码的基础上,符号位不变,数值取反,0变1,1变0。
-56 ==> 10111000 (原码)
11000111 (反码)
-56 + 1 = -55
-55 ==> 11001000 (反码)
-55 <== 10110111 (原码)
负数运算时,如果不跨0,没有任何问题,如果跨0,就会与实际结果有1的偏差
-4+4 = 0
-4 ==> 10000100(原码) 11111011(反码)
+4 = 11111111 (反码)== > 10000000 (正码)==> -0
-4+5 = 1
-4 ==> 10000100(原码) 11111011(反码)
+5 = 00000000 (反码)== > 00000000 (正码)==> +0
所以引入补码
补码:正数的补码是其本身,负数的补码是在其反码的基础上+1。
十进制数字 | 原码 | 反码 | 补码 |
---|---|---|---|
+0 | 00000000 | 00000000 | 00000000 |
-0 | 10000000 | 11111111 | 00000000 |
-1 | 10000001 | 11111110 | 11111111 |
-2 | 10000010 | 11111101 | 11111110 |
-3 | 10000011 | 11111100 | 11111101 |
-4 | 10000100 | 11111011 | 11111100 |
… | … | … | … |
-127 | 11111111 | 10000000 | 10000001 |
-128 | 无 | 无 | 10000000 |
为了解决负数计算时跨0的问题而出现的。
正数的补码不变,负数的补码在反码的基础上+1
另外补码还能多记录一个特殊的值-128,该数据在一个字节下,没有反码和原码、
计算机中的存储和计算都是以补码的形式进行的。
public class Test{
public static void main(Strinf[] args){
int a = 300;// 00000000 00000000 00000001 00101100
byte b = (byte)a;
System.out.println(b);// 00101100 ==> 44
}
}
00101100 (原码)== > 00101100(反码)> 00101100(补码)> 44
public class Test{
public static void main(Strinf[] args){
int a = 200;// 00000000 00000000 00000000 11001000
byte b = (byte)a;
System.out.println(b);// 11001000 ==> -56
}
}
11001000(原码)== > 10110111(反码)== > 10111000(补码)==> -56
运算符 | 含义 | 运算规则 |
---|---|---|
& | 逻辑与 | 0为false,1为true |
| | 逻辑或 | 0为false,1为true |
<< | 左移 | 向左移动,低位补0 |
>> | 右移 | 向右移动,高位补0或1 |
>>> | 无符号左移 | 向右移动,高位补0 |
public class Test{
public static void main(Strinf[] args){
int a = 200;// 00000000 00000000 00000000 11001000
int b = 10; // 00000000 00000000 00000000 00001010
System.out.println(a & b);
}
}
00000000 00000000 00000000 11001000
& 00000000 00000000 00000000 00001010
00000000 00000000 00000000 00001000 ==> 8
public class Test{
public static void main(Strinf[] args){
int a = 200;// 00000000 00000000 00000000 11001000
int b = 10; // 00000000 00000000 00000000 00001010
System.out.println(a & b);
}
}
00000000 00000000 00000000 11001000
| 00000000 00000000 00000000 00001010
00000000 00000000 00000000 11001010 ==> 202
public class Test{
public static void main(Strinf[] args){
int a = 200;// 00000000 00000000 00000000 11001000
System.out.println(a << 2);//800
}
}
public class Test{
public static void main(Strinf[] args){
int a = 200;// 00000000 00000000 00000000 11001000
System.out.println(a >> 2);// 50
}
}