js中小数精度问题

  目录

js中的小数精度问题分析

js中小数精度问题

我们在日常开发中,是否遇到过0.1+0.2,一看马上答案就出来了,0.3啊,多么简单的加法,但是,如果你在代码里运行一下,结果出乎意料哦,是0.30000000000000004,哈哈,有意思吧,不仅在js中这样,java,python等语言都是这个德行。
奇怪了,这是为什么呢?这就需要了解一下小数在计算机中的存储方式了。
我在这里只说小数部分的保存方式。
先来说一下小数如何存储,如0.6:

  • 将该数字乘以2,取出整数部分作为二进制表示的第1位;然后再将小数部分乘以2,将得到的整数部分作为二进制表示的第2位;以此类推,直到小数部分为0。
  • 特殊情况: 小数部分出现循环,无法停止,则用有限的二进制位无法准确表示一个小数,这也是在编程语言中表示小数会出现误差的原因
    再具体的分步骤看一下:
    1
    2
    3
    4
    5
    6
    0.6 * 2 = 1.2 —————— 1 
    0.2 * 2 = 0.4 —————— 0
    0.4 * 2 = 0.8 —————— 0
    0.8 * 2 = 1.6 —————— 1
    0.6 * 2 = 1.2 —————— 1
    …………

我们可以发现在该计算中已经出现了循环,0.6用二进制表示为 1001 1001 1001 1001 ……
如果是10.6,那个10.6的完整二进制表示为 1010.100110011001……
通过上边的解释,就知道为什么有的小数在js里会出现精度不准的问题了吧,接下来,我们再看看二进制小数如何还原成十进制。
我们还拿0.6这个小数来举例子,1001 1001 1001 1001 :

  • 从左到右,v[i] * 2^( - i ), i 为从左到右的index,v[i]为该位的值,直接看例子,很直接的
    1
    0.6 = 1 * 2^-1 + 0 * 2^-2 + 0 * 2^-3 + 1 * 2^-4 + ……

好了,通过上面大概的了解了小数为什么精度有时候不准的问题,这也只是粗略的理解一下而已,具体在各种语言中运行时可能情况会很复杂,我就点到而止了。