处理区块链中大数的转化,显示整数部分使用千分位,保留精度
在我们写区块链中常遇到后端返回的非常大的数字,需要前端处理显示,一开始我们使用数字直接除以18个0,会发现在整除的时候会莫名的出现一堆长的数字丢失了相应的精度。是因为浮点数值的最高进度是17位小数。
我们可以使用ethers自带的utils中的大数处理方法来做,在js文件中写一些公共的方法
import {utils} from 'ethers'
// 去除多余的0保留特定小数有效数字 export function effective(val: any,nums=4) { if (!val) return val; val = String(val); if (val.includes('e')) { val = changEtoS(val) } let dot = val.includes("."); if (val == 0 || val === "undefined") { return "0"; } if (dot) { let array = val.split(".")[1].split(""); let start = array.findIndex((item: any)=>item!='0'); let tempVal = val.slice(0, start+nums + val.split(".")[0].length + 1); let str = String(parseFloat(tempVal)); return str.includes('e') ? tempVal : clearZoo(tempVal); //去除尾部多余的0 } else { return val; } }
export function addThousandthSign(numStr) { //处理数字的千分 let regForm = /(\d{1,3})(?=(\d{3})+(?:$|\.))/g; //小数点也分千分位 numStr = String(numStr); if (numStr.includes('.')) { let num = numStr.split('.')[0]; let dotNum = numStr.split('.')[1]; let resultStr = num.toString().replace(regForm, "$1,"); return `${resultStr}.${dotNum}`; } else { return numStr.toString().replace(regForm, "$1,") } } export function changE(str) {//将String 大数后带e的转成不带e的字符串 let num = str.split('e')[0]; let deci = str.split('+')[1]; return utils.formatUnits(utils.parseUnits(num, deci), 18) } export function getResultData(val) { var valStr = String(val);//当数字过大时转换会出现e小数点精度最多保留14位最后一位四舍五入但是一般也够用了 var tempStr = valStr.includes('e') ? changE(valStr) : utils.formatUnits(valStr, 18); return addThousandthSign(effective(tempStr)); }
然后在页面中引入 getResultData 函数直接把大数传过去就可以得到对应的值了
import {getResultData} from '@/utils/index.js' methods: { getResultData(val){ return getResultData(val); }, getData() { this.getResultData(97825000000000000000000) //97,825 this.getResultData(97825435960000000000000)//97,825.4359 } }
不停学习,热爱是源源不断的动力。