黑马程序员技术交流社区
标题: 浮点数计算为什么有误差? [打印本页]
作者: 试试扎哇 时间: 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 |