1. 类型和值:Number 和 BigInt
Number 类型的舍入误差怎么理解?解决方式有哪些?
舍入误差 : 由于JavaScript的小数位有限,一些无线循环小数无法正确表示,会导致一些误差存在
- 先将转换为整数,相加后再转换为小数,如下
- 使用number对象中的toFixed方法可以指定小数位
- es6新增Number.EPSILON方法
let x = (0.1*10+0.2*10)/10;console.log(x === 0.3) //true
学习 BigInt 类型(参考 MDN)
描述
可以用在一个整数字面量后面加
n的方式定义一个BigInt,如:10n,或者调用函数BigInt()但不包含new运算符,并传递一个整数值或者字符串值
const thiBiggestInt = 9007199254740991n;const alsoHuge = BigInt(9007199254740991);cosnt hugeString = BigInt("9007199254740991n");cosnt hugeHex = BigInt("0x1fffffffffff");const hugeBin = BigInt("0b11111111111111111111111111111111111111111111111111111")
它在某些方面类似于Number,但是也有几个关键的不同点:
- 不能用于
Math对象中的方法;- 不能和任何
Number实例混合运算,两者必须转换成同一种类型.在两种类型来回转换时要小心,因为BigInt变量在转换成Number变量时可能会精度丢失
类型信息
使用typeof测试时,BigInt对象返回”bigint”:
typeof ln === 'bigint' //truetypeof BigInt('1') === 'bigint' //true
运算
以下操作可以和BigInt一起使用:+,-,*,/,**,%,出>>>(无符号右移)之外的位操作也是支持,因为BigInt都是有符号的,BigInt不支持单目(+)操作
const previousMaxSafe = BigInt(Number.MAX_SAFE_INTEGER);// ↪ 9007199254740991nconst maxPlusOne = previousMaxSafe + 1n;// ↪ 9007199254740992nconst theFuture = previousMaxSafe + 2n;// ↪ 9007199254740993n, this works now!const multi = previousMaxSafe * 2n;// ↪ 18014398509481982nconst subtr = multi – 10n;// ↪ 18014398509481972nconst mod = multi % 10n;// ↪ 2nconst bigN = 2n ** 54n;// ↪ 18014398509481984nbigN * -1n// ↪ –18014398509481984n
/操作符对于整数的运算也没问题,可是因为这些变量是BigInt而不是BigDecimal.该操作符结果会向零取整,也就是说不会返回小数部分
警告:当使用
BigInt时,带小数的运算会被取整。
const expected = 4n / 2n;// ↪ 2nconst rounded = 5n / 2n;// ↪ 2n, not 2.5n
比较
BigInt和Number不是严格相等的,但是宽松相等的.
0n === 0 //false0n == 0 //true
BigInt和Number可以进行比较
1n < 2 // true2n > 1 // true2 > 2 //false2n > 2 // false2n >= 2 // true
两者也可以混在一个数组内排序
const mixed = [4n, 6, -12n, 10, 4, 0, 0n];// ↪ [4n, 6, -12n, 10, 4, 0, 0n]mixed.sort();// ↪ [-12n, 0, 0n, 10, 4n, 4, 6]
注意被Object包装的BigInt使用object的比较规则进行比较,只用同一个对象在比较时才会相等
0n === Object(0n); //falseObject(0n) === Object(0n); //falseconst o = Object(0n);o === o //true
条件
if (0n) {console.log('Hello from the if!');} else {console.log('Hello from the else!');}// ↪ "Hello from the else!"0n || 12n// ↪ 12n0n && 12n// ↪ 0nBoolean(0n)// ↪ falseBoolean(12n)// ↪ true!12n// ↪ false!0n// ↪ true
静态方法
BigInt.asIntN()
将 BigInt 值转换为一个 -2^(width-1) 与 2^(width-1) - 1 之间的有符号整数。
BigInt.asUintN()
将一个 BigInt 值转换为 0 与 2^(width) - 1 之间的无符号整数。
实例方法
BigInt.prototype.toLocaleString()
返回此数字的language-sensitive形式的字符串.覆盖 `Object.prototype.toLocaleString()`
BigInt.prototype.toString()
返回以指定技术(base)表示指定数字的字符串
BigInt.prototype.valueOf()
返回指定对象的基元值
实现一个大数相加算法
const { log } = console;// 输入两个巨大的整数型字符串const arr1 = '9'.repeat(19);const arr2 = '7'.repeat(15);// 输出一个正确的字符串表示相加结果function add(arr1, arr2) {const arr1Re = [...arr1].reverse();const arr2Re = [...arr2].reverse();let flag= 0;const res = [];while(arr1Re.length > 0 || arr2Re.length > 0) {let t1 = arr1Re.pop() || 0;let t2 = arr2Re.pop() || 0;let tmp = t1 + t2 + flag;flag = Math.floor(tmp/10);res.unshift(tmp%10);}if(flag) {res.unshift(flag)}log(res.join(""))}const result = add(arr1, arr2);log(result);
