js精度问题之bignumber.jsdecimal.js的基本使用

news/2024/11/24 11:32:01/

一、背景

JavaScript中存在精度缺失问题
在这里插入图片描述
为什么?

主要是由于浮点数的表示方式以及计算机的二进制运算原理导致的

JavaScript使用IEEE 754标准定义了浮点数的表示和计算规则。在这种表示方式中,浮点数由符号位、指数位和尾数位组成。尾数位的长度是固定的,一般为53位。但是,无论是整数还是小数,都需要通过二进制表示来存储,而不是十进制。这就导致了某些十进制小数在二进制表示中是无限循环的,因此无法完全精确地表示。

例如,0.1这个十进制小数在二进制中是无限循环的,无法准确表示。因此,在进行计算时,可能会出现舍入误差。多次的舍入误差累积起来就会导致精度缺失问题。

此外,JavaScript中的数值计算是通过二进制进行的,而不是十进制。由于二进制和十进制之间的转换存在精度限制,导致一些十进制的小数无法完全准确地转换为二进制,进而引发精度缺失。

为了解决这个问题,可以使用一些特殊的库或技术,如BigNumber.jsDecimal.js,来处理大数和小数运算,以提高精度和准确性。另外,在涉及到金额计算等需要高精度的场景中,可以将数值转换为整数进行计算,然后再进行必要的除法或格式化操作,以减少精度缺失的影响。

二、Decimal

1、decimal介绍

decimal.js文档地址:decimal.js

decimal.js是使用二进制来计算的,所以可以更好地实现格化式数学运算,对数字进行高精度处理;使用decimal类型处理数据可以保证数据计算更为精确,还可以节省储存空间。
在这里插入图片描述
这里的精度是根据有效数字而不是小数位来指定的,并且所有计算都四舍五入到精度(类似于 Python 的十进制模块),而不仅仅是涉及除法的计算

2、使用方法

安装

npm install --save decimal.js

页面引入

import { Decimal } from 'decimal.js'

加减乘除


const a = 2.998;
const b = 8.035;
// 加法
let c = new Decimal(a).add(new Decimal(b)) 
// 减法
let d = new Decimal(a).sub(new Decimal(b))
// 乘法
let e = new Decimal(a).mul(new Decimal(b))
// 除法
let f = new Decimal(a).div(new Decimal(b))
const a = 0.00002
const b = 0.00001
this.aaa = Decimal(a).add(Decimal(b))
console.log(this.aaa)

打印后
在这里插入图片描述

3、decimal.js函数封装

// 引入 Decimal.js 库
const Decimal = require('decimal.js');// 封装加法函数
function add(num1, num2) {const decimal1 = new Decimal(num1);const decimal2 = new Decimal(num2);return decimal1.plus(decimal2).toString();
}// 封装减法函数
function subtract(num1, num2) {const decimal1 = new Decimal(num1);const decimal2 = new Decimal(num2);return decimal1.minus(decimal2).toString();
}// 封装乘法函数
function multiply(num1, num2) {const decimal1 = new Decimal(num1);const decimal2 = new Decimal(num2);return decimal1.times(decimal2).toString();
}// 封装除法函数
function divide(num1, num2) {const decimal1 = new Decimal(num1);const decimal2 = new Decimal(num2);return decimal1.dividedBy(decimal2).toString();
}// 使用示例
console.log(add('0.1', '0.2'));       // 输出:0.3
console.log(subtract('1.5', '0.8'));  // 输出:0.7
console.log(multiply('2.5', '1.2'));  // 输出:3
console.log(divide('6', '2'));        // 输出:3

三、Bignumber

1、bignumber介绍

bignumber.js文档地址:bignumber.js
在这里插入图片描述

2、使用方法

npm install bignumber.js
import BigNumber from "bignumber.js"
  • 加法 .plus(n [, base]) ⇒ BigNumber
  • 减法 .minus(n [, base]) ⇒ BigNumber
  • 乘法 .times(n [, base]) ⇒ BigNumber
  • 除法 .div(n [, base]) ⇒ BigNumber
  • 取模/取余: .mod(n [, base])
  • 指数运算: .pow(n [, m]) ⇒ BigNumber
  • 开平方:.sqrt() ⇒ BigNumber
  • 比较大小: .comparedTo(n [, base]) ⇒ number
  • 精度调整 .dp([dp [, rm]]) ⇒ BigNumber|number
  • 取整:.integerValue([rm]) ⇒ BigNumber
  • 有效数字 .sd([d [, rm]]) ⇒ BigNumber|number
  • 保留小数位数 .toFixed([dp [, rm]]) ⇒ string
let x = 6.2000, y = 3.10, z = 9;
console.log('9999--plus---',BigNumber(0.7).plus(x).plus(y).toString());  // 10
console.log('9999--minus---',BigNumber(x).minus(2).toString());  // 4.2
console.log('9999--times---',BigNumber(x).times(10).toString());  // 62
console.log('9999--div---',BigNumber(x).div(y).toString());  // 2
console.log('9999--mod---',BigNumber(x).mod(y).toString());  // 0
console.log('9999--pow---',BigNumber(x).pow(-2).toString());  // 0.0260145681581685744
console.log('9999--sqrt---',BigNumber(z).sqrt().toString());  // 3
console.log('9999--toFixed---',BigNumber(x).toFixed(1).toString());  // 6.2
console.log('9999--integerValue---',BigNumber(x).integerValue(1).toString());  // 6
console.log('9999--sd---',BigNumber(x).sd().toString());  // 2
console.log('9999--comparedTo---',BigNumber(x).comparedTo(y).toString());  //1, 1为大于,-1为小于,0为等于

http://www.ppmy.cn/news/584788.html

相关文章

nuxt 设置i18n后多语言文件不会动态更新

nuxt 设置i18n后多语言文件不会动态更新 昨天遇到的一个问题,然后研究了一整天,今天才得到解决 nuxt 设置i18n多语言时多语言文件不会动态更新 我的原始代码如下: {modules: [nuxtjs/i18n,],i18n: {locales: [{code: en,iso: en-US,name:…

武汉理工大学自动化学院研究生07年就业情况(官方统计)

http://bbs.kaoyan.com/t2701374p1 专业 就业单位 地点 电力电子与电力传动 武汉商贸职业学院 湖北省武汉市 电力电子与电力传动 四川民生石油天然气勘察设计有限公司 四川省成都市 电力电子与电力传动 武汉光迅科技股份有限…

致dudu,分享一下服务器组装与配置

先声明,该文章没有牵涉到.NET 程序设计,但是该服务器是为了给我公司提供sps与.NET服务的。 前几天cnblogs的服务器出现问题,接着由dudu提出为blogs配置第二台服务器的想法,并实行自愿捐款。在此,我也贡献一点自己微薄的…

电脑买回来了

以后晚上就再也不用在办公室呆着了,可以回住的地方做点饭,一边吃一边看东西。晚上也可以熬熬夜,搞点东西。 01年刚工作时候就想着买电脑,可惜当时没钱,只好一直盼望着盼望着,直到如今,电脑配置…

7月18日自助装机配置专家点评

标题类型作者地区时间不到9000的超级游戏高清方案游戏发烧方案raywyzy 2008-7-17 11:11:45 装机理由高性能的CPU4G内存4870显卡22寸显示器,游戏高清绝对都是非常的畅快 配件数量单价品牌型号CPU11175Intel Core 2 Quad Q6600/散装散热系统1249Tt Ruby Orb(CL-P0391)主板1899昂…

Java线程

线程是一个单独程序流程。多线程是指一个程序可以同时运行多个任务,每个任务由一个单独的线程来完成。也就是说,多个线程可以同时在一个程序中运行,并且每一个线程完成不同的任务。程序可以通过控制线程来控制程序的运行,例如线程…

无为

早上得知一年前帮亲戚DIY的电脑出问题了(具体问题还不明确,但最怕是软件方面的问题,因为在那些对电脑不太了解的人们头脑中,软硬不分家,软件出现问题电脑质量差)。更恶劣的事情发生了,据说请了一位修电脑的“专业户”&…

RockerMQ集群管理工具mqadmin详细目录参数

文章目录 1.mqadmin命名的使用方式2.Topic相关的命令参数3.集群相关的命令参数4.Broker相关的命令参数5.消息相关命令参数6.消费者、消费组相关命令参数7.连接相关的命令参数8.NameServer相关的命令参数8.监控相关的命令参数 1.mqadmin命名的使用方式 RocketMQ提供有控制台及一…