IT评测·应用市场-qidao123.com
标题:
前端数字精度丢失原因息争决方案
[打印本页]
作者:
科技颠覆者
时间:
2025-1-3 14:20
标题:
前端数字精度丢失原因息争决方案
前言
本地源码预览:https://gitcode.com/weixin_44862629/vue-study.git
在项目开发中,一般比较重要的数值计算是交给后端处理,再返还给前端,(比方:订单金额、科学数据)。
但在一些项目,前端不得不自己处理数值计算,这是就有大概遇到精度丢失
比方:后端返回数字型id , 9999999999994322924 前端读取到的值 9999999999994323000
一、为什么会造成精度丢失?
1.1 超过最值
当数字超过-900719925474099 【+(2^53 – 1)】 或 9007199254740991时会出现精度丢失题目(后端返回数字id)
1.2 浮点数(javaScript数字存储规范)
关键字:IEEE 754规范53 位有效数字, 计算机二进制和十进制的互相编译
1、 JavaScript使用IEEE 754规范存储数字, 其规定双精度浮点数使用 64 位(8 字节) 来存储一个浮点数,可以表示二进位制的53 位有效数字。
2、在计算机语言中,其底层是对数据举行了二进制转换,存储的是二进制编码。
结论:在我们 输入\输出 数字时,其实举行了二进制和十进制的互相编译;这时某一个编译环节数据大概超过53位,同时IEEE 754规定了53 位有效数字。导致了浮点数精度丢失
二、精度不高的运算(小数据)
在处理浮点数计算且精度要求不高时,可以使用js自带数字处理方法
// toFixed() 保留指定小数位数,返回字符串
let num = 3.14159;
let formattedNum = num.toFixed(2); // "3.14"
// parseFloat() 配合toFixed(),转回数字类型
Number.parseFloat(num.toFixed(2)) // 3.14
// 使用Math.round()、Math.floor()和Math.ceil()方法
let roundedNum = Math.round(num * 100) / 100; // 3.14 舍入到两位小数
let floorNum = Math.floor(num * 100) / 100; // 3.14 向下舍入到两位小数
let ceilNum = Math.ceil(num * 100) / 100; // 3.15,但只有在第三位小数是5或更大时才会真正向上舍入
// 利用正则表达式匹配小数位,移除多余的内容
复制代码
三、化整计算(小数据)
对浮点数先扩大为整数,计算之后在还原倍数.
需要根据小数位数设置倍数;若接近16位数字,有大概出现超过最值精度丢失
/**
* @param num1 数据1
* @param num2 数据2
* @param multiple 要扩大的倍数
*/
const computedNum = (num1: number, num2: number, multiple: number) => {
return (num1 * multiple + num2 * multiple) / multiple;
};
console.log(computedNum(0.1, 0.2, 10)) //0.3
复制代码
四、BigInt类型(Es6)(超过最值)
BigInt是JavaScript在ES2020中引入的一种新的根本数据类型,用于表示任意精度的整数
BigInt可以表示任意长度的整数,没有固定的上限和下限
4.1 BigInt声明
提示1:BigInt不是数字类型,不能使用处理数字的方法。下方组件也没有时使用【数字输入框】
提示2:BigInt只能和BigInt举行数学运算
const bigIntValue = BigInt(9999999999994322924); // 方式一
const bigIntValue = 9999999999994322924n; // 方式二
复制代码
截图中输入框使用的数据分别是:9999999999994322924、9999999999994322924n
<el-input /> 暂时不支持BigInt类型
<div class="mrg-b20">
未进行处理:
<el-input-number
style="width: 350px"
v-model="num5"
controls-position="right"
/>
= <el-input style="width: 350px" v-model="res3" />
</div>
<p style="color: tomato;"> 提示:下方是文本输入框,输入数字实际是字符串,数据在js绑定 </p>
<div>
已进行BigInt处理:
<el-input
style="width: 350px"
v-model="num6"
:min="0"
controls-position="right"
/>
= {{ num6 }}
</div>
const num5 = ref(9999999999994322924);
const res3 = computed(() => {
return num5.value;
});
const num6 = ref(9999999999994322924n);
console.log(num6.value); // 9999999999994322924n
复制代码
五、第三方库(超过最值)
第三方库适用场景Big.js能够处理高精度的浮点数运算。它提供了加、减、乘、除等根本运算功能,适用于大数和需要高精度浮点运算的场景Decimal.js支持十进制浮点数运算。它能够处理复杂的金融计算,适用于需要高精度计算的场景BigNumber.js提供了精确的数学运算功能,适用于各种需要高精度计算的场景math.js不仅支持高精度计算,还提供了丰富的数学函数和常量,适用于复杂的数学计算需求number-precision专门用于处理JavaScript计算精度的库,可以在Vue项目中引用,提供加减乘除以及四舍五入的干系方法
JSONbig.parse 是用于解析 JSON 字符串的,而不是直接用于处理 JavaScript 对象
<div>
已进行JSONbig处理:
<el-input
style="width: 350px"
v-model="res5"
:min="0"
controls-position="right"
/>
</div>
import JSONbig from "json-bigint";
const jsonString = '{"num": 9999999999994322924}';
const res5 = computed(() => {
return JSONbig.parse(jsonString).num;
});
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/)
Powered by Discuz! X3.4