为什么float、double计算会精度缺失?
答:
整数位的二进制转10进制方式:1 * 2^n次方,
所以对于整数10进制转二级制,就用一直除2,余数再除2:
6
6 / 2 = 3
3/ 2 = 1 余1
1/ 2 = 0 余1
转成二进制为:110
对于任何一个整数, 一直除2,肯定能除尽,最后余1。
可是对于小数的二进制转10进制方式:* 1 * 2^-n次方。也就是相当于 1/ 2^n方,是个除法。
所以对于小数10进制转二进制,就会一直乘2,去掉进位再乘2 。
比如0.625,整数位是0,小数位625会一直乘2,
625 * 2 = 125 进了一位 1
25 * 2 = 50
50 * 2 = 100 进了一位 1
所以小数位二进制表示为:101
小数位二进制101转换成整数转换方式为:
1 * 2^-1 + 0 * 2^-2 + 1 * 2^-3 = 0.5 + 0 + 1/ 8 = 0.5 + 0.125 = 0.625
可是对于小数10进制转2进制,一直乘2。很容易一直乘下去,或者造成循环,所以存储位数用完了之后就只能0舍1入(因为到位数很靠后之后,可以舍去比如 1 * 2^-20 = 1 / 2^20无限趋近于0了)。
所以小数位表示的时候都存在约等于(0舍1入),再进行运算自然容易出现精度丢失的问题。**
比如0.3:
3 *2 = 6
6 * 2 = 12 进一位 1
2 * 2 = 4
4 * 2 = 8
8 * 2 = 16 进一位1
6 * 2 = 12 进一位1
2 * 2 = 4 开始循环了
010011 010011 010011