# 数学对象

  • Math.abs(-5) 取绝对值
  • Math.celi(5.3) 向上取整
  • Math.floor(5.8) 向下取整
  • Math.round(3.5) 四舍五入
  • Math.max(12,34,25) 取最大值
  • Math.min(3,5,8) 取最小值
  • Math.random() 获取0~1之间的随机数

# 0.1 + 0.2 != 0.3

为什么 0.1 + 0.2 != 0.3

在计算机里所有的数据存储和运算都会转为二进制来进行

十/二进制转化

小数位十进制转二进制:十进制小数转换成二进制小数采用"乘2取整,顺序排列"法。具体做法是:用2乘十进制小数,可以得到积,将积的整数部分取出,再用2乘余下的小数部分,又得到一个积,再将积的整数部分取出,如此进行,直到积中的小数部分为零,此时0或1为二进制的最后一位。或者达到所要求的精度为止。

然后把取出的整数部分按顺序排列起来,先取的整数作为二进制小数的高位有效位,后取的整数作为低位有效位。

// 0.1 转为二进制
0.1 * 2 = 0.2 // 整数位为 0 此时二进制数为 0.0
0.2 * 2 = 0.4 // 整数位为 0 此时二进制数为 0.00
0.4 * 2 = 0.8 // 整数位为 0 此时二进制数为 0.000
0.8 * 2 = 1.6 // 整数位为 1 此时二进制数为 0.0001
0.6 * 2 = 1.2 // 整数位为 1 此时二进制数为 0.00011
0.2 * 2 = 0.4 // 整数位为 0 此时二进制数为 0.000110
// ...... 无限循环了

(0.1).toString(2) // 0.1 在浏览器中转二进制结果 双进度浮点数,最后向上四舍五入了,会比正常的 0.1 大了一点
// "0.0001100110011001100110011001100110011001100110011001101"

(0.2).toString(2) // 同理
"0.001100110011001100110011001100110011001100110011001101"

// 所以最终 0.1 + 0.2 的二进制求和后转十进制为 0.30000000000000004
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Number 类型表示我们通常意义上的“数字”。这个数字大致对应数学中的有理数,当然,在计算机中,我们有一定的精度限制。

JavaScript 中的 Number 类型有 18437736874454810627(即 2^64-2^53+3) 个值。

JavaScript 中的 Number 类型基本符合 IEEE 754-2008 规定的双精度浮点数规则,但是 JavaScript 为了表达几个额外的语言场景(比如不让除以 0 出错,而引入了无穷大的概念),规定了几个例外情况:

  • NaN,占用了 9007199254740990,这原本是符合 IEEE 规则的数字;
  • Infinity,无穷大;
  • -Infinity,负无穷大。

另外,值得注意的是,JavaScript 中有 +0 和 -0,在加法类运算中它们没有区别,但是除法的场合则需要特别留意区分,“忘记检测除以 -0,而得到负无穷大”的情况经常会导致错误,而区分 +0 和 -0 的方式,正是检测 1/x 是 Infinity 还是 -Infinity。

根据双精度浮点数的定义,Number 类型中有效的整数范围是 -0x1fffffffffffff 至 0x1fffffffffffff,所以 Number 无法精确表示此范围外的整数。

同样根据浮点数的定义,非整数的 Number 类型无法用 ==(=== 也不行) 来比较,一段著名的代码,这也正是我们第三题的问题,为什么在 JavaScript 中,0.1+0.2 不能 =0.3:

console.log(0.1 + 0.2 == 0.3) // false
1

这里输出的结果是 false,说明两边不相等的,这是浮点运算的特点,也是很多同学疑惑的来源,浮点数运算的精度问题导致等式左右的结果并不是严格相等,而是相差了个微小的值。

所以实际上,这里错误的不是结论,而是比较的方法,正确的比较方法是使用 JavaScript 提供的最小精度值:

console.log( Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON);
1

检查等式左右两边差的绝对值是否小于最小精度,才是正确的比较浮点数的方法。这段代码结果就是 true 了。

内容来自:极客时间 https://time.geekbang.org/column/article/78884

相关解决方案 number-precisionbignumber.js