1+53+11 === 64
零
现实里没有 0
和 -0
,但是 JS 使用的 IEEE754 标准里有的,JS 里做了一些手脚😎使得直接比较两者是相同的。
-0 === 0
// true
但是,最好 0 不要用来做除数,也不要使用 Object.is()
(1 / 0) === (1 / -0)
// false
Object.is(0, -0);
// false
Number
JS 内置很多不可变的 number 对象,每个数值字面量实质是对这些不可变 number 对象的引用。字面量值与 number 对象值很接近或者完全吻合。
Number 挂载了一些有用的常量。Number.EPSILON
保存的是最小的正数。当两数之差小于此数,JS 可以认为两数相等。
比如这个经典场景:
0.1 + 0.2 - 0.3
// 5.551115123125783e-17
0.1 + 0.2 - 0.3 < Number.EPSILON
// true
Number.MAX_SAFE_INTEGER
约 9000 万亿,就是 2 ** 53 - 1
打印的结果。
同理,Number.MIN_SAFE_INTEGER
是 - (2 ** 53 - 1)
。
** 在一个期望为整数的运算中,只有所有参与运算的因子,运算结果,中间结果都是在安全整数范围内时,才可以进行精确的整数运算。**Number.isSafeInteger
可以判断是否是安全的整数。
Number.MAX_VALUE
是 JS 的 Number 类型中最大的值,等于 Number.MAX_SAFE_INTEGER * 2 ** 971
,其精度损失很大。Number.MIN_VALUE
是 JS 中无限逼近 0 的数,值是 2 ** -1074
,其精度损失很大。
运算符
取余运算
%
取决于被除数,取模运算(JS 不支持)取决于除数。
位运算符
JS 做位运算时,有个坑:参与位运算的 number 类型会被转换为 32 位有符号整型(Java 的 int)进行计算,在得到计算结果后,再转换为 JS 的数值类型。虽然 JS 有 54 位安全整数,但是参与位运算时最高的 22 个位会被丢掉,没有任何警告信息。
所以,当你想用左移和右移代替乘除时,要注意这个坑。
当对负数进行右移时,使用带符号的右移 >>
而不是 >>>
-2 >> 1
// -1
-2 >>> 1
// 2147483647
解析 Number 的函数
function deconstruct(number) {
// 数值 = 符号位 * 系数 * (2 ** 指数)
let sign = 1; // 符号位
let coefficient = number; // 系数
let exponent = 0; // 2 ** 指数
if (coefficient < 0) {
coefficient = -coefficient;
sign = -1;
}
if (Number.isFinite(number) && number !== 0) {
exponent = -1128;
let reduction = coefficient;
// 系数不断除 2, 直到趋近于 0 为止, 将除 2 次数与 - 1128 相加, 结果即变量 exp 的值
while (reduction !== 0) {
exponent += 1;
reduction /= 2;
}
reduction = exponent;
// 当指数为 0 时, 可以认为这个值是整数了.
while (reduction > 0) {
coefficient /= 2;
reduction -= 1;
}
while (reduction < 0) {
coefficient *= 2;
reduction += 1;
}
return {
sign, coefficient, exponent, number
}
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论。