1: 计算机中数据的表达/存储方式
在人类语言中,有正数,有负数… …
在计算机中,数据的表达方式为
正数存储在计算机中的形式为原码,
负数在计算机的存储形式为补码,
字节(byte)是内存的基本单位,计算机存储和管理数据以字节为最小单位
2: 计算机中二进制的表示和在编辑器如eclipse的展现方式
在计算机字长为32位(简单理解为32位的机器)的机器中,
正整数+5,在计算机内部表示为:00000000 00000000 00000000 00000101
但是我们在使用编辑器如eclilse的时候,如使用如下API
Integer.toBinaryString(5)
则其输出为101,这是因为编辑器对内容做了处理,在这里我们只要知道在计算机内部,101会根据计算机的字长进行补0操作就好
3:由二进制带来的一些弊端
如果在编辑器中使用二进制存储,则长度会很长,因此衍生出十六进制和八进制的概念
int a = 0x2f;//小写十六进制
System.out.println(Integer.toBinaryString(a));
int b = 0x2F;//大写十六进制
System.out.println(Integer.toBinaryString(b));
此处我们应该注意:大写的十六进制和小写的十六进制是没有区别的
它由0-9,A-F组成,字母不区分大小写
int c = 10;//标准十进制
System.out.println(Integer.toBinaryString(c));
int d = 010;//以零开头,表示八进制
System.out.println(Integer.toBinaryString(d));
4:知识补充
4.1:Java中的数据类型
int 整形 大小:32位
byte 字节 大小:8位
shot 短整形 大小:16位
… ….
举例:int占4个字节,每个字节是8位
4.2:Java中进制转换的API
Integer.toBinaryString(int) 十进制转二进制
Integer.toHexString(int) 十进制转十六进制
Integer.parseInt(String s) 将s以十进制返回
Integer.parseInt(String s, int radix) 将s以radix进制返回
如下代码表示,将由二进制表示的binary输出为十进制
private void binaryToDecimalism(String binary){
System.out.println(Integer.parseInt(binary,2));
}
如下代码表示,将decimalism转换为二进制
private void decimalismToBinary(int decimalism){
System.out.println(Integer.toBinaryString(decimalism));
}
这里如果输入是
decimalismToBinary(7)
binaryToDecimalism("1100100")
则对应输出为
111
100
但是如果decimalismToBinary方法输入为-7,则输出为
11111111111111111111111111111001
这里就涉及到另一个知识点了,负数在计算机中的变现形式:补码
先说负整数7转换为二进制的过程,这里其实就是补码的求解
(1)把-7转化成7,二进制是 111
(2)Java中对于不满32位的int二进制自动补齐,所以变成了 (29个0)111
(3)然后取反 (29个1)000
(4)然后加1 (29个1)001
4.3 原码,反码,补码
计算机中为什么不适用原码来表示数据,反而多了反码和补码这样的一个概念,简单的来说就是为了避免和简化因为符号带来的复杂运算
4.3.1 原码
原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:
[+1]原 = 0000 0001
[-1]原 = 1000 0001
4.3.2 反码
正数的反码是其本身
负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.
[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反
4.3.3 补码
正数的补码就是其本身
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
[+1] = [00000001]原 = [00000001]反 = [00000001]补
[-1] = [10000001]原 = [11111110]反 = [11111111]补
对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.
4.4 左移<< , 有符号右移>> , 无符号右移>>>
4.4.1 左移位<<,有符号的移位操作
左移操作时将运算数的二进制码整体左移指定位数,左移之后的空位用0补充
4.4.2 右移位>>,有符号的移位操作
右移操作是将运算数的二进制码整体右移指定位数,右移之后的空位用符号位补充,如果是正数用0补充,负数用1补充。
4.4.3 无符号右移(注意:并没有无符号左移)>>> 无符号右移操作是将运算数的二进制码整体右移指定位数,右移之后的空位用全都用0 填充。
无符号右移不管正负号,移完后全都补0,
正数左移或者右移后的2进制转换为10进制即为结果。
负数左移或者右移时先取反(符号位不变)加1后,再左移或者右移,在取反(符号位不变)加1变成补码后,再转化为10进制。
举例
12<<2 = 48(12左移2位结果为48) 00000000 00000000 00000000 0000 1100
为12的二进制,现在把12左移2位变为:00000000 00000000 00000000 0011 0000 在转化为十进制为:4812>>2 = 3 00000000 00000000 00000000 0000 1100 为12的二进制,现在把12右移2位变为:
00000000 00000000 00000000 0000 0011在把其转化为十进制为:3-12 >>2 = - 3 由上知负数左移或者右移时先取反加1,即:10000000 00000000 00000000 0000 1100 为12的原码,取反为:11111111 11111111 11111111 1111 0011,在加1为:11111111
11111111 11111111 1111 0100,在把-12左移2位为:11111111 11111111 11111111
1111 1101,在取反加1为:100000000 00000000 00000000 0000 0011转换为十进制为:-312>>>2 = 3 12的无符号右移与12的右移结果一样为:3
-12>>>2 = 1073741821 由上知负数左移或者右移时先取反加1,即:10000000 00000000 00000000 0000 1100 为-12的原码,取反(符号位不变)为:11111111 11111111 11111111 1111
0011,在加1为:11111111 11111111 11111111 1111 0100,在把-12右移2位为:00111111
11111111 11111111 1111 1101,在把他转化为十进制为:1073741821