A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

运算浮点数的时候,发现计算结果和我们预想的不一致
    代码如下:
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


0 个回复

您需要登录后才可以回帖 登录 | 加入黑马