黑马程序员技术交流社区

标题: 浮点数计算为什么有误差? [打印本页]

作者: 试试扎哇    时间: 2018-10-7 21:51
标题: 浮点数计算为什么有误差?
运算浮点数的时候,发现计算结果和我们预想的不一致
    代码如下:
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







欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2