java浮点数计算机中储存方式
float类型 占据空间32位4字节
| 符号位(S):1bit | 指数位(E):8bit | 尾数位(M):23bit |
|---|
double类型 占据空间64位8字节
| 符号位(S):1bit | 指数位(E):11bit | 尾数位(M):52bit |
|---|
特别注意的是指数位存放的是补码,底数是2!
具体举例:
1.十进制转二进制
整数部分
十进制整数转二进制数:“除以2取余,逆序排列”(短除反取余法)
- 例: 89(10) =10110012(2)
除数 被除数 余数 2 89 2 44 1 2 22 0 2 11 0 2 5 1 2 2 1 2 1 0 2 0 1
小数部分
十进制小数转二进制数:“乘以2取整,顺序排列”(乘2取整法)
- 例: 0.625(10)= 0.101(2)
乘数 * 乘数 = 积 整数 0.625 X 2 = 1.25 1 0.25 X 2 = 0.5 0 0.5 X 2 = 1.0 1
转换结果
由上两步可知,89.625(10)转换为二进制位1011001.101(2)
在计算机中的储存方式
float f = 89.625f;
- 计算符号位:因为为正数,所以符号位为 0。
- 计算指数位:规范化表示小数点左边只能有一位并且为1,所以为1.011001101 x 26,规定指数位的底为2且幂加127(double类型加1023),所以指数位为133(127+6),转换为二进制——>1000 0101(2)。
- 计算尾数位:规定尾数位去掉规范化前边的整数位的1,只保存小数,所以尾数位为 ——> 011001101
最终得到的完整的浮点数为: 0 10000101 01100110100000000000000
符号位 指数位 尾数位 0 10000101 01100110100000000000000
2.二进制转十进制
- 例: 1011.01
- (2)
- =(1×2
- 3
- +0×2
- 2
- +1×2
- 1
- +1×2
- 0
- +0×2
- -1
- +1 × 2
- -2
- )
- (10)
- = (8+0+2+1+0+0.25) (10)
- = 11.25 (10)
规律:个位上的数字的次数是0,十位上的数字的次数是1,…,依奖递增,而十分位的数字的次数是-1,百分位上数字的次数是-2,…,依次递减。
注意:不是任何一个十进制小数都能转换成有限位的二进制数。
数据类型强转
double in = 1.0256789123; // in = 1.0256789123
float f = (float)in; // f = 1.0256789; double 强转为float会造成精度丢失
int i = (int) f; // i = 1;强转为 int类型 会丢失全部的小数位
强转注意:
值得引起注意的是: 浮点数强转,并不像整形强转那样,直接将数据一刀切
- 例如:383
- (10)
- 对应的2进制为 0000 0001 0111 1111
强转为byte类型
值为127 (10) 对应的二进制位 0111 1111
直接丢失高位字节
获取浮点数的整数位与小数位
获取浮点数的整数位
public int zhengshuwei(double in){
return (int)in;
}
获取浮点数的小数位
public double xiaoshu(double in){
int flag = (int)in;
return in - flag;
}
若要将一个浮点数按其二进制强转为整形需调用其引用类型
long res = Double.doubleToLongBits(s);
根据其二进制获取数据的小数部分
/**
* @param s Double.doubleToLongBits(s);转过来的值
* 即double数据对应的二进制的值
*/
public static double xiaoshu(long s) {
int len = (int) ((s >>> 52 & 0x7ff )- 1023);//float - 127 >>> 23
len = 52 - len;
double res=0;
for(int i=0-len;i<0;i++) {
res += (s & 1) * Math.pow(2, i);
s >>>= 1;
}
return res;
}
根据其二进制获取数据的整数部分
public static int zhengshu(long s) {
int len = (int) ((s >>> 52 & 0x7fff )- 1023);//float - 127 >>> 23
return (int) (((s & 0xfffffffffffffl) >> (52 - len)) + (1 << len));
}