@@ -132,70 +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
142
- Number .isInteger (true ) // false
143
140
```
144
141
145
- 注意,由于 JavaScript 浮点数采用的是 IEEE 754 标准,表示数值时最多只能存储 53 位二进制位数(1 位隐藏位与 52 位有效位)。超出位数上限时,第 54 位会尝试是否往第 53 位进位(0 不进位,1 进位),它和它往后的位数一概丢弃,这种情况下可能会导致误判 。
142
+ JavaScript 内部,整数和浮点数采用的是同样的储存方法,所以 25 和 25.0 被视为同一个值 。
146
143
147
144
``` 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
157
147
```
158
148
159
- 数值的大小在 -1 与 1 之间(不含两个端点)时,其绝对值小于 ` Number.MIN_VALUE ` 即视为 0 。
149
+ 如果参数不是数值, ` Number.isInteger ` 返回 ` false ` 。
160
150
161
151
``` 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
+ ```
166
157
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
170
162
```
171
163
172
- 因此,在金融、天文等领域的数据精度要求较高、判断值是否整数的情况下,不建议使用 ` Number.isInteger() ` 原生函数,请使用包含正则的函数替代 。
164
+ 上面代码中, ` Number.isInteger ` 的参数明明不是整数,但是会返回 ` true ` 。原因就是这个小数的精度达到了小数点后16个十进制位,转成二进制位超过了53个二进制位,导致最后的那个 ` 2 ` 被丢弃了 。
173
165
174
- ES5 可以通过下面的代码,部署 ` Number.isInteger() ` 。
166
+ 类似的情况还有,如果一个数值的绝对值小于 ` Number.MIN_VALUE ` (5E-324),即小于 JavaScript 能够分辨的最小值,会被自动转为 0。这时, ` Number.isInteger ` 也会误判 。
175
167
176
168
``` 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
192
171
```
193
172
173
+ 上面代码中,` 5E-325 ` 由于值太小,会被自动转为0,因此返回` true ` 。
174
+
175
+ 总之,如果对数据精度的要求较高,不建议使用` Number.isInteger() ` 判断一个数值是否为整数。
176
+
194
177
## Number.EPSILON
195
178
196
179
ES6 在` Number ` 对象上面,新增一个极小的常量` Number.EPSILON ` 。根据规格,它表示 1 与大于 1 的最小浮点数之间的差。
197
180
198
- 对于 64 位浮点数来说,大于 1 的最小浮点数相当于二进制的` 1.00..001 ` ,小数点后面有连续 51 个零。这个值减去 1 之后,就等于 2 的-52 次方。
181
+ 对于 64 位浮点数来说,大于 1 的最小浮点数相当于二进制的` 1.00..001 ` ,小数点后面有连续 51 个零。这个值减去 1 之后,就等于 2 的 -52 次方。
199
182
200
183
``` javascript
201
184
Number .EPSILON === Math .pow (2 , - 52 )
@@ -539,24 +522,24 @@ Math.imul(0x7fffffff, 0x7fffffff) // 1
539
522
540
523
### Math.fround()
541
524
542
- ` Math.fround ` 方法返回一个数的单精度浮点数形式 。
525
+ ` Math.fround ` 方法返回一个数的32位单精度浮点数形式 。
543
526
544
- 对于 -2 的 24 次方至 2 的 24 次方(不含两端)的整数 ,返回结果与参数本身一致。
527
+ 对于32位单精度格式来说,数值精度是24个二进制位(1 位隐藏位与 23 位有效位),所以对于 -2< sup >24</ sup > 至 2< sup >24</ sup > 之间的整数(不含两个端点) ,返回结果与参数本身一致。
545
528
546
529
``` javascript
547
530
Math .fround (0 ) // 0
548
531
Math .fround (1 ) // 1
549
532
Math .fround (2 ** 24 - 1 ) // 16777215
550
533
```
551
534
552
- 单精度浮点数采用 IEEE 754 标准,最多由 24 位二进制位数(1 位隐藏位与 23 位有效位)表达数值,若参数绝对值大于 2 的 24 次方 ,返回的结果便开始丢失精度。
535
+ 如果参数的绝对值大于 2< sup >24</ sup > ,返回的结果便开始丢失精度。
553
536
554
537
``` javascript
555
538
Math .fround (2 ** 24 ) // 16777216
556
539
Math .fround (2 ** 24 + 1 ) // 16777216
557
540
```
558
541
559
- ` Math.fround ` 方法主要将双精度浮点数转为单精度浮点数,第 25 位二进制数尝试往上一位进位,它与它往后的位数全部丢弃 。
542
+ ` Math.fround ` 方法的主要作用,是将64位双精度浮点数转为32位单精度浮点数。如果小数的精度超过24个二进制位,返回值就会不同于原值,否则返回值不变(即与64位双精度值一致) 。
560
543
561
544
``` javascript
562
545
// 未丢失有效精度
@@ -569,7 +552,7 @@ Math.fround(0.7) // 0.699999988079071
569
552
Math .fround (1.0000000123 ) // 1
570
553
```
571
554
572
- 对于 ` NaN ` 和 ` Infinity ` ,此方法返回原值。其它类型而言 ,` Math.fround ` 方法会将其转为数值再返回单精度浮点数 。
555
+ 对于 ` NaN ` 和 ` Infinity ` ,此方法返回原值。对于其它类型的非数值 ,` Math.fround ` 方法会先将其转为数值,再返回单精度浮点数 。
573
556
574
557
``` javascript
575
558
Math .fround (NaN ) // NaN
@@ -585,7 +568,7 @@ Math.fround({}) // NaN
585
568
对于没有部署这个方法的环境,可以用下面的代码模拟。
586
569
587
570
``` javascript
588
- Math .fround = Math .fround || function (x ) {
571
+ Math .fround = Math .fround || function (x ) {
589
572
return new Float32Array ([x])[0 ];
590
573
};
591
574
```
0 commit comments