转浮点数丢失精度的问题

2018-08-22  本文已影响26人  cocoa

现象

NSNumber *num = @111.11;
float f = num.floatValue;
NSLog(@"%f",f);

打印log,f值为111.110001

NSNumber *num = @11.11;
float f = num.floatValue;
NSLog(@"%f",f);

打印log,f值为111.110000

原因

十进制小数111.11表示成浮点数为

//双精度
0100000001011011110001110000101000111101011100001010001111010111
//单精度
01000010110111100011100001010010

十进制小数11.11表示成浮点数为

//单精度
01000001001100011100001010001111

比较小数部分(0.11)

//双精度
00011100001010010  //单精度 111.11
00011100001010001111  //单精度 11.11
0001110000101000111101011100001010001111010111 //双精度 111.11

因为二进制小数只能准确表示以2的次方为分母的分数,所以十进制小数不能一一对应一个二进制小数,我们看到十进制小数0.11转换成二进制小数是一个无限小数。因为浮点数的有效位数是有限的,所以我们拿到的是近似等于0.11的二进制浮点数。

0001110000101000111101011100001010001111010111 //46位
//舍入至20位
00011100001010001111 //等于十进制的0.109999656677246
//舍入至17位
00011100001010010 //等于十进制的0.110000610351563

浮点数的显示精确到小数点后6位,也就是我们看到的0.110000和0.110001

结论

浮点数能提供越多的有效位数,浮点数的值就越接近他所表示的值。

上一篇下一篇

猜你喜欢

热点阅读