JavaScript:解决计算精度问题/mathjs/bignumber.js/big.js/decimal.js

简介: JavaScript:解决计算精度问题/mathjs/bignumber.js/big.js/decimal.js

一、计算精度现象举例

举例1、加法

举例2、减法

举例3、乘法

举例3、除法

二、JS为什么会有计算精度的问题

JavaScript 内部只有一种数字类型Number,也就是说,JavaScript 语言的底层根本没有整数,所有数字都是以IEEE-754标准格式64位浮点数形式储存,1与1.0是相同的。因为有些小数以二进制表示位数是无穷的。JavaScript会把超出53位之后的二进制舍弃,所以涉及小数的比较和运算要特别小心。

IEEE二进制浮点数算术标准(IEEE 754)是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用。这个标准定义了表示浮点数的格式(包括负零-0)与反常值(denormal number)),一些特殊数值(无穷(Inf)与非数值(NaN)),以及这些数值的“浮点数运算符”;它也指明了四种数值舍入规则和五种例外状况(包括例外发生的时机与处理方式)。

三、解决方法

项目技术栈vue3+vite+ts

3.1、方法一,同时扩大倍数再除以相同的倍数

(x * 10 ^ n + y * 10 ^ n)/ 10 ^ n

0.1 +0.2
// 0.30000000000000004
(0.1 *10 + 0.2 *10) / 10
// 0.3

3.2、方法二,toFixed保留小数位数,依然存在精度问题

3.3、方法三,mathjs - npm

pnpm add mathjs

Weekly Download 580197 (20230324)

方法 运算 使用 运输结果

add

加法

add(1, 2)

3

subtract

减法

subtract(2, 1)

1

multiply

乘法

multiply(2, 2)

4

divide

除法

divide(4, 2)

2

round

四舍五入

round(4.01)

4

bignumber

转换为bigNumber类型。对于具有任意精度的计算,math.js支持BigNumber数据类型,bignumber返回一个Decimal类,精度依然难以保证

bignumber(4.01)

evaluate

直接运算表达式

evaluate('(4.01 + 3) / 2')

3.505

sqrt

平方根计算

sqrt(4)

2

pow

x 的 y 次幂值 pow(3,3) 27

chain

链式操作

chain(3).add(4).multiply(2).done()

14

atan2

返回其参数商的反正切值

atan2(15,30)

0.4636476090008061
log 返回给定数字的自然Log值(即e的底数)

log(9)

2.1972245773362196

pi

圆周率

console.log('pi:', pi)

3.141592653589793
e 欧拉常数和自然对数的基数,约为 2.718

console.log('e:', e)

2.718281828459045

derivative

待考证

console.log('derivative:',derivative('x^2 + x', 'x'))

matrix

矩阵操作

matrix([0, 1, 2,  3, 4])

3.4、方法四,bignumber.js - npm

Weekly Download 8826960 (20230324)

pnpm add bignumber.js

const num = new BigNumber(1234567890.0123456789)

const num1 = new BigNumber(123.123)

方法 运算 使用 运算结果

toFormat

格式化

num.toFormat()

1,234,567,890.0123458 保留了七位小数,第七位依据第八位四舍五入

toFormat

格式化

num.toFormat(3)

1,234,567,890.012 保留三位小数

toFormat

格式化

num.toFormat(13)

1,234,567,890.012 保留十三位小数,实际还是保留了七位小数,第七位依据第八位四舍五入,然后位数用0补足

plus

加法

num1.plus(1.1)

minus

减法

num1.minus(1.1)

times

乘法

num1.times(2)

div

除法

num1.div(2)

mod

取余

num1.mod(2)

x.eq(y)

isEqualTo--是否相等

num.eq(num1)

false

x.gt(y)

isGreaterThan--是否大于

num.gt(num1)

true

x.gte(y)

isGreaterThanOrEqualTo--是否大于等于

num.gte(num1)

true

x.lt(y)

isLessThan--是否小于

num.lt(num1)

false

x.lte(y)

isLessThanOrEqualTo--是否小于等于

num.lte(num1)

false

negated

取非,改变数字的正负号

num.negated()

3.5、方法五,big.js - npm

Weekly Download 21,339,420 (20230324)

pnpm add @types/big.js

const num = new Big(1234567890.0123456789)

const num1 = new Big(123.123)

方法 运算 使用 运算结果

plus

加法

num1.plus(1.1)

minus

减法

num1.minus(1.1)

times

乘法

num1.times(2)

div

除法

num1.div(2)

mod

取余

num1.mod(2)

x.eq(y)

isEqualTo--是否相等

num.eq(num1)

false

x.gt(y)

isGreaterThan--是否大于

num.gt(num1)

true

x.gte(y)

isGreaterThanOrEqualTo--是否大于等于

num.gte(num1)

true

x.lt(y)

isLessThan--是否小于

num.lt(num1)

false

x.lte(y)

isLessThanOrEqualTo--是否小于等于

num.lte(num1)

false

3.6、方法六,decimal.js - npm

Weekly Download 16,251,713 (20230324)

pnpm add decimal.js

 const num = new Big(1234567890.0123456789)

const num1 = new Big(123.123)

方法 运算 使用 运算结果

plus

加法

num1.plus(new Decimal(1.1))

minus

减法

num1.minus(new Decimal(1.1))

times

乘法

num1.times(new Decimal(2))

div

除法

num1.div(new Decimal(2))

mod

取余

num1.mod(new Decimal(2))

x.eq(y)

isEqualTo--是否相等

num.eq(num1)

false

x.gt(y)

isGreaterThan--是否大于

num.gt(num1)

true

x.gte(y)

isGreaterThanOrEqualTo--是否大于等于

num.gte(num1)

true

x.lt(y)

isLessThan--是否小于

num.lt(num1)

false

x.lte(y)

isLessThanOrEqualTo--是否小于等于

num.lte(num1)

false

四、欢迎交流指正,关注我,一起学习。

相关文章
|
12天前
|
JavaScript 前端开发 算法
JavaScript 中通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能,JS中排序算法的使用详解(附实际应用代码)
Array.sort() 是一个功能强大的方法,通过自定义的比较函数,可以处理各种复杂的排序逻辑。无论是简单的数字排序,还是多字段、嵌套对象、分组排序等高级应用,Array.sort() 都能胜任。同时,通过性能优化技巧(如映射排序)和结合其他数组方法(如 reduce),Array.sort() 可以用来实现高效的数据处理逻辑。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
1月前
|
JavaScript 前端开发
JavaWeb JavaScript ③ JS的流程控制和函数
通过本文的详细介绍,您可以深入理解JavaScript的流程控制和函数的使用,进而编写出高效、可维护的代码。
76 32
|
4月前
|
JavaScript 前端开发
|
12天前
|
数据采集 JavaScript 前端开发
JavaScript中通过array.filter()实现数组的数据筛选、数据清洗和链式调用,JS中数组过滤器的使用详解(附实际应用代码)
用array.filter()来实现数据筛选、数据清洗和链式调用,相对于for循环更加清晰,语义化强,能显著提升代码的可读性和可维护性。博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
3月前
|
JavaScript 前端开发
【JavaScript】——JS基础入门常见操作(大量举例)
JS引入方式,JS基础语法,JS增删查改,JS函数,JS对象
|
4月前
|
JavaScript 前端开发 Java
springboot解决js前端跨域问题,javascript跨域问题解决
本文介绍了如何在Spring Boot项目中编写Filter过滤器以处理跨域问题,并通过一个示例展示了使用JavaScript进行跨域请求的方法。首先,在Spring Boot应用中添加一个实现了`Filter`接口的类,设置响应头允许所有来源的跨域请求。接着,通过一个简单的HTML页面和jQuery发送AJAX请求到指定URL,验证跨域请求是否成功。文中还提供了请求成功的响应数据样例及请求效果截图。
springboot解决js前端跨域问题,javascript跨域问题解决
|
4月前
|
JavaScript 前端开发
Moment.js与其他处理时间戳格式差异的JavaScript库相比有什么优势?
Moment.js与其他处理时间戳格式差异的JavaScript库相比有什么优势?
|
4月前
|
JSON JavaScript 前端开发
使用JavaScript和Node.js构建简单的RESTful API
使用JavaScript和Node.js构建简单的RESTful API
|
5月前
|
缓存 JavaScript 前端开发
探索Vue.js中的计算属性与侦听器
【10月更文挑战第5天】探索Vue.js中的计算属性与侦听器
62 1
|
5月前
|
人工智能 JavaScript 前端开发
使用Node.js模拟执行JavaScript
使用Node.js模拟执行JavaScript
59 2

热门文章

最新文章