目录
Javascript是非数据安全类型的语言,所以JS尾数精度有丢失的问题
Number类型
通过查阅JS官方文档
在JS定义的浮点数会自动转换为Number类型,Number类型是一个双精度64位浮点数,二进制存储格式执行IEEE 754标准
通过查阅维基百科,64位二进制格式IEEE 754的定义
Number能处理的最大安全值和最小安全值分别为:
对于JS来说超过\(2^{53}-1=9007199254740991\)和\(-2^{53}+1=-9007199254740991\)都是不安全的
比如:
精度是如何丢失的
const m1 = 9007199254740991;
推导过程,10进制转2进制转IEEE:
9007199254740991
= \(2^{53}-1\)
= \(2^{52}+2^{51}+2^{50}+...+2^{2}+2^{1}+2^{0}\)
= 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
+ 0100 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
+ 0010 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
...
+ 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0100
+ 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010
+ 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001
= 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111
= 1.111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 * \(2^{52}\)
符号位:正数 = 0
指数:52 = 000 0011 0100
尾数:1.111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111
IEEE:0000 0011 0100 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111
还原:
1.111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 * \(2^{52}\)
= 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 (小数点右移52位)
= 9007199254740991
const m2 = 9007199254740992;
推导过程,10进制转2进制转IEEE:
9007199254740992
= 1 * \(2^{53}\)
= 1 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
符号位:正数 = 0
指数:53 = 000 0011 0101
尾数:1 = 1 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 000(最后一位溢出)
IEEE:0000 0011 0101 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
还原:
1 * \(2^{53}\)
= 1 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000(小数点右移53位)
= 9007199254740992(虽然与期望值9007199254740992相同,但是实际上丢失了最后一位0)
const m3 = 9007199254740993;
推导过程,10进制转2进制转IEEE:
9007199254740993
= 1 * \(2^{53}\) + 1
= 1 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001
符号位:正数 = 0
指数:指数 = 000 0011 0101
尾数:1 = 1 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 000(最后一位溢出)
IEEE:0000 0011 0101 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
还原:
1 * \(2^{53}\)
= 1 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000(小数点右移53位)
= 9007199254740992(与期望值9007199254740993不同,最后一位1丢失)
const m4 = 9007199254740994;
9007199254740994
= 1 * \(2^{53}\) + 2
= 1 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010
符号位:正数 = 0
指数:指数 = 000 0011 0101
尾数:
1.0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010
= 1 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 001(最后一位溢出)
IEEE:0000 0011 0101 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001
还原:
1.0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 001 * \(2^{53}\)
= 1 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010(小数点右移53位)
= 9007199254740994(虽然与期望值9007199254740994相同,但是实际上丢失了最后一位0)
标签:0000,0011,53,JS,1111,丢失,const,IEEE,精度 From: https://www.cnblogs.com/ylc0x01/p/17340915.html