浮点数float或者说双精度浮点数double运算为什么不精确,其实这句话本身就有问题,本身这个数据类型就很“很不自信”了(精度。。。),相对精确一点的说法是:十进制的小数,计算机内部无法用二进制的小数来精确表示。 什么是二进制的小数?就是比如101.11这个数字,如果是十进制的,那这个数字可以这么拆解: 101.11就等于 1 * 10^2 + 0 * 10^1 + 1 * 10^0 + 1 * 10^{-1} + 1 * 10^{-2} = 100 + 0 + 1 + 0.1 + 0.01 = 101.11 注意:现在如果是二进制的,数字只能是0和1。 101.11就等于 1 * 2^2 + 0 * 2^1 + 1 * 2^0 + 1 * 2^{-1} + 1 * 2^{-2} = 4 + 0 + 1 + 1/2 + 1/4 = 5.75 可以推导出来: 对于二进制小数,小数点右边能表达的值是 1/2, 1/4, 1/8, 1/16, 1/32, 1/64, 1/128 ... 1/(2^n) 计算机只能用这些个 1/(2^n)之和来表达十进制的小数。 现在问题来了,我们来试一试如何用二进制来表达十进制的 0.2 吧。 0.01 = 1/4 = 0.25,太大 0.001 = 1/8 = 0.125,太小 0.0011 = 1/8 + 1/16 = 0.1875,逼近0.2了 0.00111 = 1/8 + 1/16 + 1/32 = 0.21875,又大了 0.001101 = 1/8 + 1/16 + 1/64 = 0.203125,还是大 0.0011001 = 1/8 + 1/16 + 1/128 = 0.1953125,这结果不错 0.00110011 = 1/8 + 1/16 + 1/128 + 1/256 = 0.19921875已经很逼近了,等于是精确到小数点后8位为止默认是“精确”的。 这就是为什么说用二进制小数没法精确表达十进制小数的含义。
—— 本文来自火龙信奥(义乌睿码科技):义乌青少年信息学奥赛与编程教育平台,专注 CSP-J/S、NOIP、GESP 竞赛培训,线上线下融合教学,助力编程升学。网址:hlcoding.com