IT评测·应用市场-qidao123.com

标题: 前端数字精度丢失原因息争决方案 [打印本页]

作者: 科技颠覆者    时间: 2025-1-3 14:20
标题: 前端数字精度丢失原因息争决方案

前言

本地源码预览:https://gitcode.com/weixin_44862629/vue-study.git


一、为什么会造成精度丢失?

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自带数字处理方法
  1. // toFixed() 保留指定小数位数,返回字符串
  2. let num = 3.14159;
  3. let formattedNum = num.toFixed(2); // "3.14"
  4. // parseFloat() 配合toFixed(),转回数字类型
  5. Number.parseFloat(num.toFixed(2))        // 3.14
  6. // 使用Math.round()、Math.floor()和Math.ceil()方法
  7. let roundedNum = Math.round(num * 100) / 100; // 3.14 舍入到两位小数
  8. let floorNum = Math.floor(num * 100) / 100; // 3.14  向下舍入到两位小数
  9. let ceilNum = Math.ceil(num * 100) / 100; // 3.15,但只有在第三位小数是5或更大时才会真正向上舍入
  10. // 利用正则表达式匹配小数位,移除多余的内容
复制代码
三、化整计算(小数据)

对浮点数先扩大为整数,计算之后在还原倍数.
   需要根据小数位数设置倍数;若接近16位数字,有大概出现超过最值精度丢失
  1. /**
  2. * @param num1 数据1
  3. * @param num2 数据2
  4. * @param multiple 要扩大的倍数
  5. */
  6. const computedNum = (num1: number, num2: number, multiple: number) => {
  7.   return (num1 * multiple + num2 * multiple) / multiple;
  8. };
  9. console.log(computedNum(0.1, 0.2, 10)) //0.3
复制代码
四、BigInt类型(Es6)(超过最值)

   BigInt是JavaScript在ES2020中引入的一种新的根本数据类型,用于表示任意精度的整数
BigInt可以表示任意长度的整数,没有固定的上限和下限
  4.1 BigInt声明

提示1:BigInt不是数字类型,不能使用处理数字的方法。下方组件也没有时使用【数字输入框】
提示2:BigInt只能和BigInt举行数学运算
  1. const bigIntValue = BigInt(9999999999994322924);        // 方式一
  2. const bigIntValue = 9999999999994322924n; // 方式二
复制代码
  截图中输入框使用的数据分别是:9999999999994322924、9999999999994322924n
  

<el-input /> 暂时不支持BigInt类型

  1. <div class="mrg-b20">
  2.   未进行处理:
  3.   <el-input-number
  4.     style="width: 350px"
  5.     v-model="num5"
  6.     controls-position="right"
  7.   />
  8.   = <el-input style="width: 350px" v-model="res3" />
  9. </div>
  10. <p style="color: tomato;"> 提示:下方是文本输入框,输入数字实际是字符串,数据在js绑定 </p>
  11. <div>
  12.   已进行BigInt处理:
  13.   <el-input
  14.     style="width: 350px"
  15.     v-model="num6"
  16.     :min="0"
  17.     controls-position="right"
  18.   />
  19.   = {{ num6 }}
  20. </div>
  21. const num5 = ref(9999999999994322924);
  22. const res3 = computed(() => {
  23.   return num5.value;
  24. });
  25. const num6 = ref(9999999999994322924n);
  26. console.log(num6.value);         // 9999999999994322924n
复制代码
五、第三方库(超过最值)

‌第三方库适用场景Big.js‌能够处理高精度的浮点数运算。它提供了加、减、乘、除等根本运算功能,适用于大数和需要高精度浮点运算的场景‌‌Decimal.js‌支持十进制浮点数运算。它能够处理复杂的金融计算,适用于需要高精度计算的场景‌‌BigNumber.js‌提供了精确的数学运算功能,适用于各种需要高精度计算的场景‌math.js‌不仅支持高精度计算,还提供了丰富的数学函数和常量,适用于复杂的数学计算需求‌number-precision‌专门用于处理JavaScript计算精度的库,可以在Vue项目中引用,提供加减乘除以及四舍五入的干系方法‌

   JSONbig.parse 是用于解析 JSON 字符串的,而不是直接用于处理 JavaScript 对象
  1. <div>
  2.         已进行JSONbig处理:
  3.         <el-input
  4.           style="width: 350px"
  5.           v-model="res5"
  6.           :min="0"
  7.           controls-position="right"
  8.         />
  9. </div>
  10. import JSONbig from "json-bigint";
  11. const jsonString = '{"num": 9999999999994322924}';
  12. const res5 = computed(() => {
  13.   return JSONbig.parse(jsonString).num;
  14. });
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4