Skip to content

Commit 6807435

Browse files
committed
docs(Number): edit Number
1 parent b3eec5c commit 6807435

File tree

1 file changed

+29
-46
lines changed

1 file changed

+29
-46
lines changed

docs/number.md

Lines changed: 29 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -132,70 +132,53 @@ Number.parseFloat === parseFloat // true
132132

133133
## Number.isInteger()
134134

135-
`Number.isInteger()`用来判断一个值是否为整数。需要注意的是,在 JavaScript 内部,整数和浮点数采用的是同样的储存方法,所以 3 和 3.0 被视为同一个值
135+
`Number.isInteger()`用来判断一个数值是否为整数
136136

137137
```javascript
138138
Number.isInteger(25) // true
139-
Number.isInteger(25.0) // true
140139
Number.isInteger(25.1) // false
141-
Number.isInteger("15") // false
142-
Number.isInteger(true) // false
143140
```
144141

145-
注意,由于 JavaScript 浮点数采用的是 IEEE 754 标准,表示数值时最多只能存储 53 位二进制位数(1 位隐藏位与 52 位有效位)。超出位数上限时,第 54 位会尝试是否往第 53 位进位(0 不进位,1 进位),它和它往后的位数一概丢弃,这种情况下可能会导致误判
142+
JavaScript 内部,整数和浮点数采用的是同样的储存方法,所以 25 和 25.0 被视为同一个值
146143

147144
```javascript
148-
3 === 3 + 2e-16 // true
149-
Number.isInteger(3.0000000000000002) // true
150-
// 3 的二进制 2 位,2e-16 的二进制最多能表示 51 位
151-
// 第 3 ~ 53 位全为 0,直到第 55 位才开始出现 1,而这一位被丢弃了,误判为 true
152-
153-
3 + 4e-16 === 3 + 6e-16 // true
154-
Number.isInteger(3.0000000000000004) // false
155-
Number.isInteger(3.0000000000000006) // false
156-
// 第 51 位已为 1,且不会丢精度,所以 JavaScript 判定此数包含小数,返回 false
145+
Number.isInteger(25) // true
146+
Number.isInteger(25.0) // true
157147
```
158148

159-
数值的大小在 -1 与 1 之间(不含两个端点)时,其绝对值小于 `Number.MIN_VALUE` 即视为 0
149+
如果参数不是数值,`Number.isInteger`返回`false`
160150

161151
```javascript
162-
Number.MIN_VALUE // 5e-324
163-
5e-325 === 0 // true
164-
Number.isInteger(Number.MIN_VALUE) // false
165-
Number.isInteger(5e-325) // true
152+
Number.isInteger() // false
153+
Number.isInteger(null) // false
154+
Number.isInteger('15') // false
155+
Number.isInteger(true) // false
156+
```
166157

167-
3e-324 === Number.MIN_VALUE // true
168-
Number.isInteger(3e-324) // false
169-
// 同样由于精度问题,即使是比 Number.MIN_VALUE 略小的数也会被判为 5e-324。
158+
注意,由于 JavaScript 采用 IEEE 754 标准,数值存储为64位双精度格式,数值精度最多可以达到 53 个二进制位(1 个隐藏位与 52 个有效位)。如果数值的精度超过这个限度,第54位及后面的位就会被丢弃,这种情况下,`Number.isInteger`可能会误判。
159+
160+
```javascript
161+
Number.isInteger(3.0000000000000002) // true
170162
```
171163

172-
因此,在金融、天文等领域的数据精度要求较高、判断值是否整数的情况下,不建议使用`Number.isInteger()`原生函数,请使用包含正则的函数替代
164+
上面代码中,`Number.isInteger`的参数明明不是整数,但是会返回`true`。原因就是这个小数的精度达到了小数点后16个十进制位,转成二进制位超过了53个二进制位,导致最后的那个`2`被丢弃了
173165

174-
ES5 可以通过下面的代码,部署`Number.isInteger()`
166+
类似的情况还有,如果一个数值的绝对值小于`Number.MIN_VALUE`(5E-324),即小于 JavaScript 能够分辨的最小值,会被自动转为 0。这时,`Number.isInteger`也会误判
175167

176168
```javascript
177-
(function (global) {
178-
var floor = Math.floor,
179-
isFinite = global.isFinite;
180-
181-
Object.defineProperty(Number, 'isInteger', {
182-
value: function isInteger(value) {
183-
return typeof value === 'number' &&
184-
isFinite(value) &&
185-
floor(value) === value;
186-
},
187-
configurable: true,
188-
enumerable: false,
189-
writable: true
190-
});
191-
})(this);
169+
Number.isInteger(5E-324) // false
170+
Number.isInteger(5E-325) // true
192171
```
193172

173+
上面代码中,`5E-325`由于值太小,会被自动转为0,因此返回`true`
174+
175+
总之,如果对数据精度的要求较高,不建议使用`Number.isInteger()`判断一个数值是否为整数。
176+
194177
## Number.EPSILON
195178

196179
ES6 在`Number`对象上面,新增一个极小的常量`Number.EPSILON`。根据规格,它表示 1 与大于 1 的最小浮点数之间的差。
197180

198-
对于 64 位浮点数来说,大于 1 的最小浮点数相当于二进制的`1.00..001`,小数点后面有连续 51 个零。这个值减去 1 之后,就等于 2 的-52 次方。
181+
对于 64 位浮点数来说,大于 1 的最小浮点数相当于二进制的`1.00..001`,小数点后面有连续 51 个零。这个值减去 1 之后,就等于 2 的 -52 次方。
199182

200183
```javascript
201184
Number.EPSILON === Math.pow(2, -52)
@@ -539,24 +522,24 @@ Math.imul(0x7fffffff, 0x7fffffff) // 1
539522

540523
### Math.fround()
541524

542-
`Math.fround` 方法返回一个数的单精度浮点数形式
525+
`Math.fround`方法返回一个数的32位单精度浮点数形式
543526

544-
对于 -2 的 24 次方至 2 的 24 次方(不含两端)的整数,返回结果与参数本身一致。
527+
对于32位单精度格式来说,数值精度是24个二进制位(1 位隐藏位与 23 位有效位),所以对于 -2<sup>24</sup> 至 2<sup>24</sup> 之间的整数(不含两个端点),返回结果与参数本身一致。
545528

546529
```javascript
547530
Math.fround(0) // 0
548531
Math.fround(1)   // 1
549532
Math.fround(2 ** 24 - 1) // 16777215
550533
```
551534

552-
单精度浮点数采用 IEEE 754 标准,最多由 24 位二进制位数(1 位隐藏位与 23 位有效位)表达数值,若参数绝对值大于 2 的 24 次方,返回的结果便开始丢失精度。
535+
如果参数的绝对值大于 2<sup>24</sup>,返回的结果便开始丢失精度。
553536

554537
```javascript
555538
Math.fround(2 ** 24) // 16777216
556539
Math.fround(2 ** 24 + 1) // 16777216
557540
```
558541

559-
`Math.fround` 方法主要将双精度浮点数转为单精度浮点数,第 25 位二进制数尝试往上一位进位,它与它往后的位数全部丢弃
542+
`Math.fround`方法的主要作用,是将64位双精度浮点数转为32位单精度浮点数。如果小数的精度超过24个二进制位,返回值就会不同于原值,否则返回值不变(即与64位双精度值一致)
560543

561544
```javascript
562545
// 未丢失有效精度
@@ -569,7 +552,7 @@ Math.fround(0.7)   // 0.699999988079071
569552
Math.fround(1.0000000123) // 1
570553
```
571554

572-
对于 `NaN``Infinity`,此方法返回原值。其它类型而言`Math.fround` 方法会将其转为数值再返回单精度浮点数
555+
对于 `NaN``Infinity`,此方法返回原值。对于其它类型的非数值`Math.fround` 方法会先将其转为数值,再返回单精度浮点数
573556

574557
```javascript
575558
Math.fround(NaN) // NaN
@@ -585,7 +568,7 @@ Math.fround({}) // NaN
585568
对于没有部署这个方法的环境,可以用下面的代码模拟。
586569

587570
```javascript
588-
Math.fround = Math.fround || function(x) {
571+
Math.fround = Math.fround || function (x) {
589572
return new Float32Array([x])[0];
590573
};
591574
```

0 commit comments

Comments
 (0)