运算浮点数的时候,发现计算结果和我们预想的不一致 代码如下: public static void main(String[] args) {
float num1 = 0.88F;
float num2 = 0.6f;
float num = num1 - num2;
System.out.println(num);
} 运行结果: 0.27999997(理论值0.28) 引出问题: 为什么float类型数据运算中会出现误差? 分析原因: 浮点数使用IEEE Standard 754格式进行存储,float代表单精度,4个字节组成,32个二进制位; 00000000 00000000 00000000 00000000 Ø 1位代表符号位: 0代表正数,1代表负数 Ø 2-9位代表指数:00000000到11111111,可表示0到255(0和255分别特殊处理,0代表0,255代表无穷大), 因为指数需要同时表示正指数和负指数,在实际指数中引入一个偏差,对于单精度浮点数,这个偏差值是127,即可表示-126到127, Ø 10-32位代表底数:底数的小数点前一位必须为1,所以规定记住小数点后面的为底数 可以推算出:float表示的数据范围约±3.4*10^38 0.88的二进制存储形式: 将0.88换算成二进制:0.11100001010001111010 0100… 具体过程: 整数部分(模2取余):0 小数部分(乘2取整数): 0.88*2 = 1.76 1 0.76*2 = 1.52 1 0.52*2 = 1.04 1 0.04*2 = 0.08 0 0.08*2 = 0.16 0 0.16*2 = 0.32 0 0.32*2= 0.64 0 0.64*2 = 1.28 1 0.28*2= 0.56 0 0.56*2= 1.12 1
0.12*2 = 0.24 0 0.24*2= 0.48 0 0.48*2= 0.96 0 0.96*2= 1.92 1 0.92*2= 1.84 1 0.84*2= 1.68 1 0.68*2= 1.36 1 0.36*2= 0.72 0 0.72*2= 1.14 1 0.14*2= 0.28 0 0.28*2= 0.56 0 0.56*2= 1.12 1 0.12*2= 0.24 0 0.24*2= 0.48 0 … 再将0.1110000101 0001111010 0100…数字左移1位变成1.110000101 0001111010 0100*2^(-1) 指数实际是-1,必须加上偏移量127,所以为126,二进制表示:0111 1110 底数的二进制表示:110000101 0001111010 0100 综上0.88F的二进制数为:0 0111 1100 110000101 00011110100100,可以看出,这个结果是随着位数增加而无限接近0.88,23位底数是有损失精度的 ------------------------java亿亿19
|