复制来对 Number类型 相对官方的解释.
ECMAScript 中最有意思的数据类型或许就是 Number 了。Number 类型使用IEEE 754 格式表示整数和浮点值(在某些语言中也叫双精度值)。 ---红宝书
在 JavaScript 中, Number 是一种 定义为 64位双精度浮点型(double-precision 64-bit floating point format) (IEEE 754)的数字数据类型。 ---MDN
Number 类型使用IEEE 754 格式。
IEEE 754 格式
IEEE 754规定了四种表示浮点数值的方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,很少使用)与延伸双精确度(79比特以上,通常以80位实现)。
Number类型使用的便是其中的双精确度(64位)。
这张图就把结构说清了。
| 位置 | 位数 | 作用 | 表示 |
|---|---|---|---|
| 0-51 | 52 | 尾数位 | 原码表示 |
| 52-62 | 11 | 指数位 | 移码表示 |
| 63 | 1 | 符号位 | 0,1 |
举个例子
- 十进制数值:10.25
- 转化为二进制 => 1010.01
- 规格化 => 1.01001 * 2^3
- 存储: 01001放在尾数位置,3放在指数位。指数位有11位,则移码是1023+3,为100...0010,移码参考这个IEEE754表示浮点数。整个表示为这样:
到现在一个数便表示出来了。
最大值
考虑能表示的最大值,就要看
在固定位数时候所能表示的最大值。
指数位 移码最大值为11位1,原码最大值为10位1(原码最高位表示符号位),则y最大为1023,x最大表示52位1。即1.1111...1乘以 2^1023,即2^1023*(2-2^-52) 这个值也就是 Number.MAX_VALUE 的大小
最大安全整数
什么叫最大安全整数?指的也就是这个常量Number.MAX_SAFE_INTEGER
现在考虑,我们看两个数2^53与2^53+1。
-
2^53 我们尝试把它表示成二进制:1 53个0 ,规格化 1.0...00 * 2^53
-
那2^53+1呢?我们尝试把它表示成二进制:1 52个0 1 ,标准化 1.0...01 * 2^53
问题来了,尾数都有53位,但只要52个空! 它的处理办法是 忽略第53位 ,因此这两个数在计算机中表示的结果一样!
2**53===2**53+1 //true
此时就不安全了。显而易见,在2^53-1之后的数中,只要指数相同,并且尾数前52位相同,则这个两个数数值相同。