前端计算数字精度丢失问题解决方法记录 | 京东云技术团队

在日常一些需求中,总会遇到一些需要前端进行手动计算的场景,那么这里需要优先考虑的则是数字精度问题!具体请看下面截图

如图所示,在JavaScript进行浮点型数据计算当中,会出现计算结果"不正确"的现象。

我们知道浮点型数据类型主要有:单精度float、双精度double。

浮点型简单来说就是表示带有小数的数据,而恰恰小数点可以在相应的二进制的不同位置浮动,可能是因为这样就被定义成浮点型了。(不得不佩服这文化程度,定义个数据名称都这么有深度~)

但是!!!

JavaScript 存储小数和其它语言如 Java 和 Python 都不同,JavaScript 中所有数字包括整数和小数都只有一种类型 即 Number类型 它的实现遵循 IEEE 754 标准,IEEE 754 标准的内容都有什么,这个咱不用管,我们只需要记住以下一点:

javascript以64位双精度浮点数存储所有Number类型值,即计算机最多存储64位二进制数。

对于double型数据(双精度浮点数),其长度是8个字节(大小),右边52位用来表示小数点后面的数字,中间11位表示e(exponent)小数点移动的位数,左边一位用来表示正负。如图所示:

只要知道了这一点,那我们就可以对症下药(解决问题):

解决方案 ①

scss 复制代码
Number(parseFloat(20.24*100).toPrecision(16))

存储二进制时小数点的偏移量最大为52位,最多可表示的十进制为9007199254740992,对应科学计数尾数是 9.007199254740992,这也是 JavaScript 最多能表示的精度。它的长度是 16,所以可以使用 toPrecision(16) 来做精度运算。

通过先转为浮点型计算,然后做精度运算后再转为Number类型即可。

解决方案 ②

通过引入 number-precision 进行计算,步骤如下:

  • Install
sql 复制代码
npm install number-precision --save
  • Methods
scss 复制代码
NP.strip(num)         // strip a number to nearest right number
NP.plus(num1, num2, num3, ...)   // addition, num + num2 + num3, two numbers is required at least.
NP.minus(num1, num2, num3, ...)  // subtraction, num1 - num2 - num3
NP.times(num1, num2, num3, ...)  // multiplication, num1 * num2 * num3
NP.divide(num1, num2, num3, ...) // division, num1 / num2 / num3
NP.round(num, ratio)  // round a number based on ratio
  • Usage
scss 复制代码
import NP from 'number-precision'
NP.strip(0.09999999999999998); // = 0.1
NP.plus(0.1, 0.2);             // = 0.3, not 0.30000000000000004
NP.minus(1.0, 0.9);            // = 0.1, not 0.09999999999999998
NP.times(3, 0.3);              // = 0.9, not 0.8999999999999999
NP.divide(1.21, 1.1);          // = 1.1, not 1.0999999999999999
NP.round(0.105, 2);            // = 0.11, not 0.1

更多解决方案敬请关注后续更新,希望对您有帮助~

作者:京东零售 黄宏峰

来源:京东云开发者社区 转载请注明来源

相关推荐
DN金猿10 分钟前
使用npm install或cnpm install报错解决
前端·npm·node.js
丘山子11 分钟前
一些鲜为人知的 IP 地址怪异写法
前端·后端·tcp/ip
志存高远6623 分钟前
Kotlin 的 suspend 关键字
前端
www_pp_35 分钟前
# 构建词汇表:自然语言处理中的关键步骤
前端·javascript·自然语言处理·easyui
YuShiYue1 小时前
pnpm monoreop 打包时 node_modules 内部包 typescript 不能推导出类型报错
javascript·vue.js·typescript·pnpm
天天扭码1 小时前
总所周知,JavaScript中有很多函数定义方式,如何“因地制宜”?(ˉ﹃ˉ)
前端·javascript·面试
一个专注写代码的程序媛1 小时前
为什么vue的key值,不用index?
前端·javascript·vue.js
장숙혜1 小时前
ElementUi的Dropdown下拉菜单的详细介绍及使用
前端·javascript·vue.js
火柴盒zhang1 小时前
websheet之 编辑器
开发语言·前端·javascript·编辑器·spreadsheet·websheet
某公司摸鱼前端2 小时前
uniapp 仿企微左边公司切换页
前端·uni-app·企业微信