前言
本地源码预览: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企服之家,中国第一个企服评测及商务社交产业平台。 |