@@ -132,41 +132,53 @@ Number.parseFloat === parseFloat // true
132
132
133
133
## Number.isInteger()
134
134
135
- ` Number.isInteger() ` 用来判断一个值是否为整数。需要注意的是,在 JavaScript 内部,整数和浮点数是同样的储存方法,所以 3 和 3.0 被视为同一个值 。
135
+ ` Number.isInteger() ` 用来判断一个数值是否为整数 。
136
136
137
137
``` javascript
138
138
Number .isInteger (25 ) // true
139
- Number .isInteger (25.0 ) // true
140
139
Number .isInteger (25.1 ) // false
141
- Number .isInteger (" 15" ) // false
140
+ ```
141
+
142
+ JavaScript 内部,整数和浮点数采用的是同样的储存方法,所以 25 和 25.0 被视为同一个值。
143
+
144
+ ``` javascript
145
+ Number .isInteger (25 ) // true
146
+ Number .isInteger (25.0 ) // true
147
+ ```
148
+
149
+ 如果参数不是数值,` Number.isInteger ` 返回` false ` 。
150
+
151
+ ``` javascript
152
+ Number .isInteger () // false
153
+ Number .isInteger (null ) // false
154
+ Number .isInteger (' 15' ) // false
142
155
Number .isInteger (true ) // false
143
156
```
144
157
145
- ES5 可以通过下面的代码,部署 ` Number.isInteger() ` 。
158
+ 注意,由于 JavaScript 采用 IEEE 754 标准,数值存储为64位双精度格式,数值精度最多可以达到 53 个二进制位(1 个隐藏位与 52 个有效位)。如果数值的精度超过这个限度,第54位及后面的位就会被丢弃,这种情况下, ` Number.isInteger ` 可能会误判 。
146
159
147
160
``` javascript
148
- (function (global ) {
149
- var floor = Math .floor ,
150
- isFinite = global .isFinite ;
151
-
152
- Object .defineProperty (Number , ' isInteger' , {
153
- value : function isInteger (value ) {
154
- return typeof value === ' number' &&
155
- isFinite (value) &&
156
- floor (value) === value;
157
- },
158
- configurable: true ,
159
- enumerable: false ,
160
- writable: true
161
- });
162
- })(this );
161
+ Number .isInteger (3.0000000000000002 ) // true
163
162
```
164
163
164
+ 上面代码中,` Number.isInteger ` 的参数明明不是整数,但是会返回` true ` 。原因就是这个小数的精度达到了小数点后16个十进制位,转成二进制位超过了53个二进制位,导致最后的那个` 2 ` 被丢弃了。
165
+
166
+ 类似的情况还有,如果一个数值的绝对值小于` Number.MIN_VALUE ` (5E-324),即小于 JavaScript 能够分辨的最小值,会被自动转为 0。这时,` Number.isInteger ` 也会误判。
167
+
168
+ ``` javascript
169
+ Number .isInteger (5E-324 ) // false
170
+ Number .isInteger (5E-325 ) // true
171
+ ```
172
+
173
+ 上面代码中,` 5E-325 ` 由于值太小,会被自动转为0,因此返回` true ` 。
174
+
175
+ 总之,如果对数据精度的要求较高,不建议使用` Number.isInteger() ` 判断一个数值是否为整数。
176
+
165
177
## Number.EPSILON
166
178
167
179
ES6 在` Number ` 对象上面,新增一个极小的常量` Number.EPSILON ` 。根据规格,它表示 1 与大于 1 的最小浮点数之间的差。
168
180
169
- 对于 64 位浮点数来说,大于 1 的最小浮点数相当于二进制的` 1.00..001 ` ,小数点后面有连续 51 个零。这个值减去 1 之后,就等于 2 的-52 次方。
181
+ 对于 64 位浮点数来说,大于 1 的最小浮点数相当于二进制的` 1.00..001 ` ,小数点后面有连续 51 个零。这个值减去 1 之后,就等于 2 的 -52 次方。
170
182
171
183
``` javascript
172
184
Number .EPSILON === Math .pow (2 , - 52 )
@@ -510,22 +522,53 @@ Math.imul(0x7fffffff, 0x7fffffff) // 1
510
522
511
523
### Math.fround()
512
524
513
- Math.fround 方法返回一个数的单精度浮点数形式。
525
+ ` Math.fround ` 方法返回一个数的32位单精度浮点数形式。
526
+
527
+ 对于32位单精度格式来说,数值精度是24个二进制位(1 位隐藏位与 23 位有效位),所以对于 -2<sup >24</sup > 至 2<sup >24</sup > 之间的整数(不含两个端点),返回结果与参数本身一致。
528
+
529
+ ``` javascript
530
+ Math .fround (0 ) // 0
531
+ Math .fround (1 ) // 1
532
+ Math .fround (2 ** 24 - 1 ) // 16777215
533
+ ```
534
+
535
+ 如果参数的绝对值大于 2<sup >24</sup >,返回的结果便开始丢失精度。
514
536
515
537
``` javascript
516
- Math .fround (0 ) // 0
517
- Math .fround (1 ) // 1
518
- Math .fround (1.337 ) // 1.3370000123977661
519
- Math .fround (1.5 ) // 1.5
520
- Math .fround (NaN ) // NaN
538
+ Math .fround (2 ** 24 ) // 16777216
539
+ Math .fround (2 ** 24 + 1 ) // 16777216
521
540
```
522
541
523
- 对于整数来说,` Math.fround ` 方法返回结果不会有任何不同,区别主要是那些无法用 64 个二进制位精确表示的小数。这时,` Math.fround ` 方法会返回最接近这个小数的单精度浮点数。
542
+ ` Math.fround ` 方法的主要作用,是将64位双精度浮点数转为32位单精度浮点数。如果小数的精度超过24个二进制位,返回值就会不同于原值,否则返回值不变(即与64位双精度值一致)。
543
+
544
+ ``` javascript
545
+ // 未丢失有效精度
546
+ Math .fround (1.125 ) // 1.125
547
+ Math .fround (7.25 ) // 7.25
548
+
549
+ // 丢失精度
550
+ Math .fround (0.3 ) // 0.30000001192092896
551
+ Math .fround (0.7 ) // 0.699999988079071
552
+ Math .fround (1.0000000123 ) // 1
553
+ ```
554
+
555
+ 对于 ` NaN ` 和 ` Infinity ` ,此方法返回原值。对于其它类型的非数值,` Math.fround ` 方法会先将其转为数值,再返回单精度浮点数。
556
+
557
+ ``` javascript
558
+ Math .fround (NaN ) // NaN
559
+ Math .fround (Infinity ) // Infinity
560
+
561
+ Math .fround (' 5' ) // 5
562
+ Math .fround (true ) // 1
563
+ Math .fround (null ) // 0
564
+ Math .fround ([]) // 0
565
+ Math .fround ({}) // NaN
566
+ ```
524
567
525
568
对于没有部署这个方法的环境,可以用下面的代码模拟。
526
569
527
570
``` javascript
528
- Math .fround = Math .fround || function (x ) {
571
+ Math .fround = Math .fround || function (x ) {
529
572
return new Float32Array ([x])[0 ];
530
573
};
531
574
```
0 commit comments