1.简介
二进制是计算机技术中广泛采用的一种数制。二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”,由17世纪至18世纪的德国数学家莱布尼兹提出。在计算机中,所有的数据都是以0和1的形式存在的,比如CPU,内存,硬盘中的数据都是“0”和“1”。也就是说二进制只能有0、1;八进制为:0-7;十进制:0-9;十六进制比较特殊为:0-9,A(10) B(11) C(12) D(13) E(14) F(15)
2.二进制原码、反码、补码
(1)原码
所谓原码就是机器数,是加了一位符号位的二进制数(因为数值有正负之分),正数符号位为0,负数符号位为1。计算机中存储、处理、运算的数据通常是8位、16位、32位或64位的。
示例如下:
public class Test{ public static void main(String[] args) { System.out.println(toUnsignedString(10)); System.out.println(toUnsignedString(-10)); } final static char[] digits = {'0' , '1'}; /**获取原码方法,int类型32位,为了方便查看,所以循环32次 */ private static String toUnsignedString(int value) { StringBuilder sb = new StringBuilder(); int i = 32; int j = value; do { if (j >= 0) sb.insert(0,digits[j % 2]); else sb.insert(0,digits[-(j % 2)]);//因为小于0,所以得出的数值为负数,加上负号转为正数 j /= 2; i--; } while (i > 0); //格式处理一下 if(value < 0) sb.setCharAt(0, '1'); for (i = 0; i < sb.length(); i++) { if((i + 1) % 5 == 0) sb.insert(i, " "); } return sb.toString(); } }
运行结果
0000 0000 0000 0000 0000 0000 0000 1010
1000 0000 0000 0000 0000 0000 0000 1010
通过上面的案例,可以很清晰的看到二进制位的首位标识该二进制数是一个正数还是负数,其他的为真值的绝对值。
(2)反码
所谓反码就是在原码的基础上,符号位不变其他位按位取反(就是0变1,1变0)就可以了。
示例如下:
public class Test{ public static void main(String[] args) { System.out.println(toUnsignedString(10)); System.out.println(toUnsignedString(-10)); } final static char[] digits = {'0' , '1'}; /**获取原码方法,int类型32位,为了方便查看,所以循环32次 */ private static String toUnsignedString(int value) { StringBuilder sb = new StringBuilder(); int i = 32; int j = value; do { if (value > 0 && j >= 0) sb.insert(0,digits[j % 2]); else sb.insert(0,digits[-~(j % 2)]);//因为小于0,所以得出的数值为负数,加上负号转为正数 j /= 2; i--; } while (i > 0); //格式处理一下 if(value < 0) sb.setCharAt(0, '1'); for (i = 0; i < sb.length(); i++) { if((i + 1) % 5 == 0) sb.insert(i, " "); } return sb.toString(); } }
运行结果
0000 0000 0000 0000 0000 0000 0000 1010
1111 1111 1111 1111 1111 1111 1111 0101
通过上面的案例,可以很清晰的看到正数的反码 == 原码,负数的反码是在其原码的基础上,符号位(首位)不变,其余各个位取反。
(3)补码
所谓补码就是在反码的基础上按照正常的加法运算加1。
示例如下:
public class Test{ public static void main(String[] args) { System.out.println(toUnsignedString(10)); System.out.println(toUnsignedString(-10)); } final static char[] digits = {'0' , '1'}; /**获取补码方法,int类型32位,为了方便查看,所以循环32次 */ private static String toUnsignedString(int value) { StringBuilder sb = new StringBuilder(); sb.append(Integer.toBinaryString(value));//直接使用jdk自带方法获取补码 int length = sb.length(); for (int i = 0; i < 32 - length; i++) { sb.insert(0, 0); } for (int i = 0; i < sb.length(); i++) { if((i + 1) % 5 == 0) sb.insert(i, " "); } return sb.toString(); } }
运行结果
0000 0000 0000 0000 0000 0000 0000 1010
1111 1111 1111 1111 1111 1111 1111 0110
通过上面的案例,可以很清晰的看到正数的补码 == 原码,负数的补码是在其反码的基础上加1。