1. 类型和值:Number 和 BigInt

Number 类型的舍入误差怎么理解?解决方式有哪些?

舍入误差 : 由于JavaScript的小数位有限,一些无线循环小数无法正确表示,会导致一些误差存在

  • 先将转换为整数,相加后再转换为小数,如下
  • 使用number对象中的toFixed方法可以指定小数位
  • es6新增Number.EPSILON方法
  1. let x = (0.1*10+0.2*10)/10;
  2. console.log(x === 0.3) //true

学习 BigInt 类型(参考 MDN)

参考链接

描述

可以用在一个整数字面量后面加n的方式定义一个BigInt,如:10n,或者调用函数BigInt()但不包含new运算符,并传递一个整数值或者字符串值

  1. const thiBiggestInt = 9007199254740991n;
  2. const alsoHuge = BigInt(9007199254740991);
  3. cosnt hugeString = BigInt("9007199254740991n");
  4. cosnt hugeHex = BigInt("0x1fffffffffff");
  5. const hugeBin = BigInt("0b11111111111111111111111111111111111111111111111111111")

它在某些方面类似于Number,但是也有几个关键的不同点:

  1. 不能用于Math对象中的方法;
  2. 不能和任何Number实例混合运算,两者必须转换成同一种类型.在两种类型来回转换时要小心,因为BigInt变量在转换成Number变量时可能会精度丢失

类型信息

使用typeof测试时,BigInt对象返回”bigint”:

  1. typeof ln === 'bigint' //true
  2. typeof BigInt('1') === 'bigint' //true

运算

以下操作可以和BigInt一起使用:+,-,*,/,**,%,出>>>(无符号右移)之外的位操作也是支持,因为BigInt都是有符号的,BigInt不支持单目(+)操作

  1. const previousMaxSafe = BigInt(Number.MAX_SAFE_INTEGER);
  2. // ↪ 9007199254740991n
  3. const maxPlusOne = previousMaxSafe + 1n;
  4. // ↪ 9007199254740992n
  5. const theFuture = previousMaxSafe + 2n;
  6. // ↪ 9007199254740993n, this works now!
  7. const multi = previousMaxSafe * 2n;
  8. // ↪ 18014398509481982n
  9. const subtr = multi 10n;
  10. // ↪ 18014398509481972n
  11. const mod = multi % 10n;
  12. // ↪ 2n
  13. const bigN = 2n ** 54n;
  14. // ↪ 18014398509481984n
  15. bigN * -1n
  16. // ↪ –18014398509481984n

/操作符对于整数的运算也没问题,可是因为这些变量是BigInt而不是BigDecimal.该操作符结果会向零取整,也就是说不会返回小数部分

警告:当使用 BigInt 时,带小数的运算会被取整。

  1. const expected = 4n / 2n;
  2. // ↪ 2n
  3. const rounded = 5n / 2n;
  4. // ↪ 2n, not 2.5n

比较

BigIntNumber不是严格相等的,但是宽松相等的.

  1. 0n === 0 //false
  2. 0n == 0 //true

BigIntNumber可以进行比较

  1. 1n < 2 // true
  2. 2n > 1 // true
  3. 2 > 2 //false
  4. 2n > 2 // false
  5. 2n >= 2 // true

两者也可以混在一个数组内排序

  1. const mixed = [4n, 6, -12n, 10, 4, 0, 0n];
  2. // ↪ [4n, 6, -12n, 10, 4, 0, 0n]
  3. mixed.sort();
  4. // ↪ [-12n, 0, 0n, 10, 4n, 4, 6]

注意被Object包装的BigInt使用object的比较规则进行比较,只用同一个对象在比较时才会相等

  1. 0n === Object(0n); //false
  2. Object(0n) === Object(0n); //false
  3. const o = Object(0n);
  4. o === o //true

条件

  1. if (0n) {
  2. console.log('Hello from the if!');
  3. } else {
  4. console.log('Hello from the else!');
  5. }
  6. // ↪ "Hello from the else!"
  7. 0n || 12n
  8. // ↪ 12n
  9. 0n && 12n
  10. // ↪ 0n
  11. Boolean(0n)
  12. // ↪ false
  13. Boolean(12n)
  14. // ↪ true
  15. !12n
  16. // ↪ false
  17. !0n
  18. // ↪ true

静态方法

BigInt.asIntN()

  1. BigInt 值转换为一个 -2^(width-1) 2^(width-1) - 1 之间的有符号整数。

BigInt.asUintN()

  1. 将一个 BigInt 值转换为 0 2^(width) - 1 之间的无符号整数。

实例方法

BigInt.prototype.toLocaleString()

  1. 返回此数字的language-sensitive形式的字符串.覆盖 `Object.prototype.toLocaleString()`

BigInt.prototype.toString()

返回以指定技术(base)表示指定数字的字符串

BigInt.prototype.valueOf()

返回指定对象的基元值

实现一个大数相加算法

  1. const { log } = console;
  2. // 输入两个巨大的整数型字符串
  3. const arr1 = '9'.repeat(19);
  4. const arr2 = '7'.repeat(15);
  5. // 输出一个正确的字符串表示相加结果
  6. function add(arr1, arr2) {
  7. const arr1Re = [...arr1].reverse();
  8. const arr2Re = [...arr2].reverse();
  9. let flag= 0;
  10. const res = [];
  11. while(arr1Re.length > 0 || arr2Re.length > 0) {
  12. let t1 = arr1Re.pop() || 0;
  13. let t2 = arr2Re.pop() || 0;
  14. let tmp = t1 + t2 + flag;
  15. flag = Math.floor(tmp/10);
  16. res.unshift(tmp%10);
  17. }
  18. if(flag) {
  19. res.unshift(flag)
  20. }
  21. log(res.join(""))
  22. }
  23. const result = add(arr1, arr2);
  24. log(result);