共计 2128 个字符,预计需要花费 6 分钟才能阅读完成。
Number 的平安范畴
和别的强类型编程语言 (比如说 C,Java) 不同,JavaScript 不辨别整数值和浮点数值。
咱们能够发现10 === 10.0 // true
。那是因为 JavaScript 的数字类型是基于 IEEE 754 规范中的 ” 双精度 ” 格局,也就是 64 位二进制来实现的,它是通过如下格局来存储数据。
符号位 (Sign bit): 1 bit(0 示意负数,1 示意正数)
指数位 (Exponent): 11 bits
有效数字 (Significand precision): 53 bits (52 explicitly stored) 在二进制中,计算机外部保留有效数字时,第一个有效数字必然是 1
,因而这个1
并不会存储。所以 52
位有效数字能够存储 53
位。
这里能够提到的的一点是:二进制浮点数最大的问题就是在解决 0.1 + 0.2
的时候,实际上的后果不是0.3
,而是一个比拟靠近的数字0.30000000000000004
, 这也是因为在它计算的时候,会先转化为二进制,再进行计算导致的偏差。因为咱们在用 JavaScript 或者其余遵循 IEEE 754 标准的语言解决带无效数的数字时要特地留神。
JavaScript 的数字格局也就决定了 JavaScript 可能平安示意的整数范畴是 -2^53+1 ~ 2^53-1
。
这里咱们能够先明确一下“平安”的概念:
- 能够精确地示意为一个 IEEE-754 双精度数字
- 其 IEEE-754 示意不能是舍入任何其余整数以适应 IEEE-754 示意的后果
比如说:比方,2^53 - 1
是一个平安整数,它能被准确示意,在任何 IEEE-754 舍入模式(rounding mode)下,没有其余整数舍入后果为该整数。作为比照,2^53
就不是一个平安整数,它可能应用 IEEE-754 示意,然而2^53 + 1
不能应用 IEEE-754 间接示意,在就近舍入(round-to-nearest)和向零舍入中,会被舍入为2^53
。
能够参考 Number.isSafeInteger()的定义。
BigInt 类型
在 ES2020 之前,JavaScript 只有一种数值类型:number(数字),而之后为了平安表白比 -9007199254740991 ~ 9007199254740991
平安范畴之外的数字。引入了 BigInt
类型。
个别计算机是将整数存储在 CPU 的寄存器中(当初通常是 32 位或 64 位宽,JS 是 64bit),或者存储在寄存器大小的内存块中,这就会带来平安范畴的问题。而 BigInt 类型为了保障精度。它是在内存中调配一个对象。咱们让它足够大,以一系列块的模式包容所有 BigInt 的位,咱们称之为“数字”
https://v8.dev/blog/bigint
如何应用
- 间接在数字前面加一个
n
- 调用
BigInt()
构造函数
const bigInt = 9007199254740992n; // 通过间接在数字前面加 n
const bigNumber = BigInt(9007199254740992); // 对十进制数字应用 BigInt 函数
const bigString = BigInt("9007199254740992"); // 对 String 类型的应用 BigInt 函数,先隐式转换为十进制的数字,再显式转换为 BigIn 类型
const bigHex = BigInt(0x20000000000000); // 对十六进制数字应用 BigInt 函数
const bigBin = BigInt(0b100000000000000000000000000000000000000000000000000000); // 对二进制数字应用 BigInt 函数
以上这些运算生成的值都是9007199254740992n
;
BigInt 类型运算
可用操作符
BigInt 中能够使用如下操作符:
符号 | 名称 |
---|---|
+ | 加法 |
* | 乘法 |
– | 减法 |
% | 求余 |
** | 求幂 |
<< | 左移位 |
>> | 右移位 |
- 当 BigInt 应用
/
操作符时,带小数的运算会被取整。
const expected = 4n / 2n; //2n
const rounded = 5n / 2n; //2n, not 2.5n
- 因为 BigInt 都是有符号的,
>>>
(无符号右移)不能用于 BigInt
运算注意事项
BigInt 类型尽管和 Number 很像,能够做各种数学运算,然而在运算过程中要留神两点:
- BigInt 类型不能用 Math 对象中的办法。
- 不能和 Number 示例混合运算。因为 JavaScript 在解决不同类型的运算时,会把他们先转换为同一类型,而 BigInt 类型变量在被隐式转换为 Number 类型时,可能会失落精度,或者间接报错。
const number = 1;
const bigInt = 9007199254740993n;
number + bigInt; // TypeError: Cannot mix BigInt and other types
BigInt 类型和其余类型比拟
BigInt 类型的比拟和 JavaScript 中的其余类型比拟一样,分为宽松相等和严格相等。
const bigInt = 2n;
const int = 2;
const string = "2";
bigInt == int; // true
bigInt == string; // true
bigInt === int; // false
bigInt === string; //false