干货细说-Javascript-中的浮点数精度丢失问题内附好课推荐
前言最近,朋友 L 问了我这样一个问题:在 chrome 中的运算结果,为什么是这样的? 0.55 * 100 // 55.000000000000010.56 * 100 // 56.000000000000010.57 * 100 // 56.999999999999990.58 * 100 // 57.999999999999990.59 * 100 // 590.60 * 100 // 60虽然我告诉他说,这是由于浮点数精度问题导致的。但他还是不太明白,为何有的结果输出整数,有的是以 ...001 的小数结尾,有的却是以 ...999 的小数结尾,跟预想中的有差异。 这其实牵涉到了计算机原理的知识,真要解释清楚什么是浮点数,恐怕得分好几个章节了。想深入了解的同学,可以前往 这篇文章 细读。今天我们仅讨论浮点数运算结果的成因,以及如何实现我们期望的结果。 浮点数与 IEEE 754在解释什么是浮点数之前,让我们先从较为简单的小数点说起。 小数点,在数制中代表一种对齐方式。比如要比较 1000 和 200 哪个比较大,该怎么做呢?必须把他们右对齐: 1000 200发现 1 比 0(前面补零)大,所以 1000 比较大。那么如果要比较 1000 和 200.01 呢?这时候就不是右对齐了,而应该是以小数点对齐: 1000 200.01小数点的位置,在进制表示中是至关重要的。位置差一位整体就要差进制倍(十进制就是十倍)。在计算机中也是这样,虽然计算机使用二进制,但在处理非整数时,也需要考虑小数点的位置问题。无法对齐小数点,就无法做加减法比较这样的操作。 接下来的一个重要概念:在计算机中的小数有两种,定点 和 浮点。 定点的意思是,小数点固定在 32 位中的某个位置,前面的是整数,后面的是小数。小数点具体固定在哪里,可以自己在程序中指定。定点数的优点是很简单,大部分运算实现起来和整数一样或者略有变化,但是缺点则是表示范围太小,精度很差,不能充分运用存储单元。 浮点数就是设计来克服这个缺点的,它相当于一个定点数加上一个阶码,阶码表示将这个定点数的小数点移动若干位。由于可以用阶码移动小数点,因此称为浮点数。我们在写程序时,用到小数的地方,用 float 类型表示,可以方便快速地对小数进行运算。 ...