全面总结 JS 中浮点数运算不准确的原因及解决办法

"

经常会碰到一个问题,"为什么 0.1 + 0.2 !== 0.3? ",我找了很多资料,尽可能全面地分析原因和解决办法。

"

这里先给出判断方法

Math.abs(0.1+0.2-0.3) <= Number.EPSILON

IEEE 754 64 位浮点类型

IEEE 754[1]

IEEE 754 规定了四种表示浮点数值的方式:单精确度(32 位)、双精确度(64 位)、延伸单精确度(43 比特以上,很少使用)与延伸双精确度(79 比特以上,通常以 80 位实现)。

该标准的全称为 IEEE 二进制浮点数算术标准(ANSI/IEEE Std 754-1985),又称 IEC 60559:1989,微处理器系统的二进制浮点数算术(本来的编号是 IEC 559:1989)。

单精度浮点数

单精度浮点数格式是一种数据类型,在计算机存储器中占用 4 个位元(32 bits),利用“浮点”(浮动小数点)的方法,可以表示一个范围很大的数值。

在 IEEE 754-2008 的定义中,32-bit base 2 格式被正式称为 binary32 格式。这种格式在 IEEE 754-1985 被定义为 single,即单精度。需要注意的是,在更早的一些计算机系统中,也存在着其他 4 字节的浮点数格式。

定义

第 1 位表示正负,中间 8 位表示指数,后 23 位储存有效数位(有效数位是 24 位)。

中间八位共可表示 28=256 个数,指数可以是二补码;或 0 到 255,0 到 126 代表-127 到-1,127 代表零,128-255 代表 1-128。

有效数位最左手边的 1 并不会储存,因为它一定存在(二进制的第一个有效数字必定是 1)。换言之,有效数位是 24 位,实际储存 23 位。

图片

双精度浮点数

双精度浮点数(double)是计算机使用的一种数据类型。比起单精度浮点数,双精度浮点数(double)使用 64 位(8 字节) 来存储一个浮点数。它可以表示十进位制的 15 或 16 位有效数字,其可以表示的数字的绝对值范围大约是 [2.23e-308,1.79e308]

定义

和单精度类似,第 1 位表示正负,后 11 位为指数位,最后 52 位表示精确度(有效位数是 53 位)。

图片

Number in JavaScript

Number.EPSILON

Number.EPSILON === 2.220446049250313e-16,表示 1 与 Number 可表示的大于 1 的最小的浮点数之间的差值。其接近于 2**-52

Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON 可以判断 0.1 + 0.20.3 的大小。

Number.MAX_SAFE_INTEGER

Number.MAX_SAFE_INTEGER 常量表示在 JavaScript 中最大的安全整数(maxinum safe integer)(2**53 - 19007199254740991)。

因为 Javascript 的数字存储使用了 IEEE 754 中规定的双精度浮点数数据类型,而这一数据类型能够安全存储 -(2**53 - 1)2**53 - 1 之间的数值(包含边界值)。

这里安全存储的意

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值