感谢然叔老师的精彩讲解。Day01 JS整数是怎么表示的 | 面试打卡365,但是有些地方还是不怎么理解,还自以为是的走进了误区,随着不断的深入讨论研究,终于搞清楚了,所以我要总结一番。
js中的number类型采用的是64位浮点数,也就是js中的整数、小数统统都是浮点数噢。国际标准 IEEE 754中js的64个浮点数二进制位如下图,图是从然叔老师那里拷过来的。
这三个部分虽然然叔老师的文章中有,但是以我的理解再说明一下,
- sign:正负,表示一个数字是正数还是负数,在二进制中 0 为正 1 为负
- exponent:表示整数部分的指数,为11位二进制码,但是由于国际标准 IEEE 754中对这个指数偏移了1位,也就是说2^(11-1)等于1024,也就是说js中的整数最大值为2^1024,你将Number.MAX_VALUE进行指数运算,结果就是1024。
- fraction:表示浮点数中有效的小数部分,为52位二进制码噢,由于有效的小数的二进制码位数是52位,所以有效的整数的二进制码位数也是52位。由于国际标准 IEEE 754中对指数部分偏移了1位,那么自然小数部分就多加了1位,所以有效的小数的二进制码位数是53位了,有效的整数的二进制码位数也同理如此。你将Number.MAX_SAFE_INTEGER进行指数运算,结果就是53。
然后还有为啥0.1 + 0.2 不等于 0.3,这个然叔老师的文章也有说明,其实就是国际标准 IEEE 754中无法用二进制码表示不了0.1和0.2,而0.1+0.2的时候会进行二进制的运算,从而导致精度溢出,二进制码位数不足,只能进行裁剪,在裁剪的时候会对最后一位进行向上取整。
如下:
(0.1).toString(2) // 0.0001100110011001100110011001100110011001100110011001101
(0.2).toString(2)// 0.0011001100110011001100110011001100110011001100110011010
/*计算器中0.1+0.2二进制码计算结果*/// 0.0100110011001100110011001100110011001100110011001100111
(0.3).toString(2)// 0.0100110011001100110011001100110011001100110011001100110
(0.30000000000000004).toString(2)// 0.0100110011001100110011001100110011001100110011001101000
可以看出js中0.1+0.2的二进制计算结果进行了向上取整,然后将向上取整后的值转成十进制后就是0.30000000000000004
总结:这篇文章写的随意,也没啥标题,以后如果有机会研究的更加深入,再做补充。感谢然叔老师的文章和视频,让我迷途知返,感谢大圣老师以及群里同学的出谋划策,将我从理解误区中纠正过来。