![Go语言底层原理剖析](https://wfqqreader-1252317822.image.myqcloud.com/cover/131/40795131/b_40795131.jpg)
2.9 浮点数计算与精度损失
前面介绍了浮点数的表示可能丢失精度,其实在浮点数的计算过程中,也可能丢失精度。当对浮点数进行加减乘除运算时,可以采取一种直接的方式。例如对于算式0.5×0.75,0.5的浮点数表示为0|01110110|000 0000 0000 0000 0000 0000,0.75的浮点数表示为0|01110110|100 0000 0000 0000 0000 0000。由于它们的指数位相同,所以可以直接对小数位相乘,相乘后的结果为100 0000 0000 0000 0000 0000。
当前指数位的值为126,对于指数位,采取直接相加的方式126+126=252,接着减去127得到最终的指数值252-127=125。由于符号位全部为0,因此符号位的结果也为0。最终得到的结果为:0|01111101|100 0000 0000 0000 0000 0000。除法运算可以采取相同的操作。
而对于加法和减法运算,需要先调整指数值的大小,再将小数部分直接相加。例如,1.23×1028+1.00×1025需要转换为1.23×1028+0.001×1028,再对小数部分求和,结果为1.231×1028。可以发现,如果浮点数的小数部分只能精确地表示1.23,那么这个加法将被抛弃。在IEEE-754中总是会精确地计算,但是最终转换为浮点数类型时会进行四舍五入操作。在下面说明浮点数精度损失的例子中,1000个0.01相加的最终结果为9.999999999999831。
![](https://epubservercos.yuewen.com/88BA42/21190707608528606/epubprivate/OEBPS/Images/41662_55_1.jpg?sign=1738882351-rjNNevAypeI9GC3vUU3YAnKsbezacV1O-0-5b2389bd435a140645e74e283fa0e51c)
可以看出,在浮点数的计算过程中可能产生精度的损失,并且精度的损失可能随着计算的次数而累积。同时浮点数的计算顺序也会对最终的结果产生影响。加法运算由于需要进行指数调整,有丢失精度的风险,优秀的开发工程师在执行涉及加、减、乘和除的运算时,会优先执行乘法和除法运算。通常x×(y+z)可以被转换为x×y+x×z,从而得到更高的精度。