以前一直以为 -1的二进制表示是 1000 0000 0000 0000 0000 0000 0000 0001,错,大错特错,so,需要整理下,具体下文讲!!!
简单来说,整数按照位数直接存储,小数按照科学计数法存储。
一、不同进制数字的定义
int num = 1; //10进制数字定义
int num1 = 0xA; //16进制数字定义
int num2 = 017; //8进制数字定义,前边加数字0表示8进制
二、不同进制数字的转换
int num = 10;
//十进制-->二进制
Integer.toBinaryString(num)
//十进制-->16进制
Integer.toHexString(num)
//十进制-->八进制
Integer.toOctalString(num)
//二进制-->十进制
Integer.parseInt("1010", 2)
//16进制-->十进制
Integer.parseInt("A", 16)
//八进制-->十进制
Integer.parseInt("12", 8)
三、二进制数字的存储
1、int类型:
> int类型数据4字节(byte),32位(bit)。二进制最高位为符号位(0为正,1为负)
> 数字0认为是正数,所以最高位为0;
> 正数为二进制的0加 后续31位表示的实际值(例: 0000 0000 0000 0000 0000 0000 0000 1010 表示 10), 数值大小为
0 ~ (2^31-1)
> 负数为二进制1加 后续31位表示的实际值-2^32 (例:1111 1111 1111 1111 1111 1111 1111 0110 表示 -10), 数值大小为
-(2^32) ~ -1
2、float和double类型
a) 不同进制数字的表示实例:(红色表示标志位上的数值,绿色表示标志位,蓝色表示进制)
十进制整数表示143: 143(=1*10^2 + 4*10^1 + 3*10^0)
十进制小数表示143.56: 143.56(=1*10^2 + 4*10^1 + 3*10^0 + 5*10^-1 + 6*10^-2)
二进制整数表示5: 101(=1*2^2 + 0*2^1 + 1*2^0)
二进制小数表示8.5: 1000.1(=1*2^3 + 0*2^2 + 0*2^1 + 0*2^0 + 1*2^-1)
b) float和double存储结构
例:8.5(十进制) = 1000.1(二进制) = 1*2^3 + 1*2^-1(二进制)= (1*2^0 + 1*2^-4) * 2^3(二进制) = (1 + 0.0625) * 8 (十进制)
在例子中的红色部分就是机器所存储的样子,分为四部分(整数部分1、尾数部分1*2^0 + 1*2^-4、符号部分0正1负、阶数例子中的3),因为整数部分永远为1,所以不保存。所以结构如下:
数字类型 | 位数 | 符号位 | 阶码 | 尾数 |
float | 32 | 1(最高位) | 8 | 23 |
double | 64 | 1(最高位) | 11 | 52 |
float 8.5: 0 0111 1100 0001 0000 0000 0000 0000 000 绿色为符号位,红色为阶码3, 剩下的为尾数(也就是小数部分)
float -8.5: 1 0111 1100 0001 0000 0000 0000 0000 000 绿色为符号位,红色为阶码3, 剩下的为尾数(也就是小数部分)
double 8.5: 0 0111 1111 100 0001 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 绿色为符号位,红色为阶码3, 剩下的为尾数(也就是小数部分)
double -8.5: 1 0111 1111 100 0001 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 绿色为符号位,红色为阶码3, 剩下的为尾数(也就是小数部分)
注意:阶码是支持负数的,规则为(2的阶码位数次方-1-阶码值) float(2^8-1-阶码值) double(2^11-1-阶码值),即除去阶码符号位取反。