// // 引入 BigNumber 库,用于处理高精度数字计算 // import BigNumber from 'bignumber.js' // // 引入自定义的四舍五入方法 // import { useRound } from '@/commonMethods/useRound' // /** // * 转换科学计数法 // * @param value 待转换的小数,可以是数字类型或字符串类型 // * @param notationDigit 科学计数法中尾数部分保留的小数位数(四舍五入),例如 1.2344444e-5 -> 1.234e-5 // * @param numberDigit 非科学计数法时保留的小数位数(四舍五入) // * @param standard 转换为科学计数法的标准,小于这个数才会进行转换 // * @returns 转换后的科学计数法字符串,如果不满足转换条件则返回原数字的字符串形式 // */ // export function useScientificNotation(value: number | string, notationDigit = 2, numberDigit = 2, standard = 0.001) { // // 打印未处理的数据,方便调试 // console.log(value, '未处理数据') // // 如果传入的值为空,直接返回空字符串 // if (!value) { // return '' // } // // 如果传入的值为 0,直接返回字符串 '0' // if (value === 0) { // return '0' // } // // 使用 BigNumber 处理传入的值,并将其转换为字符串形式 // var res = (BigNumber(value)).toString() // // 检查结果字符串中是否包含科学计数法的标识 'E' 或 'e' // if (res.includes('E') || res.includes('e')) { // // 将 'E' 统一替换为 'e' // res = res.replace('E', 'e') // // 如果本身就是科学计数法,对尾数部分进行四舍五入处理 // // 先将字符串按 'e' 分割,对前面的尾数部分使用 useRound 方法进行四舍五入,再拼接上指数部分 // return `${useRound(res.split('e')[0], notationDigit)}e${res.split('e')[1]}` // } // // 比较传入的值和转换标准的大小,如果小于标准值则进行后续处理 // if (BigNumber(value).comparedTo(standard).toString() === '-1') { // // 检查结果字符串中是否包含小数点,只处理小数情况 // if (res.includes('.')) { // // 找到小数点在字符串中的索引位置 // const pointIndex = res.indexOf('.') // // 检查结果字符串中是否包含负号,判断是否为负数 // if (res.includes('-')) { // // 如果小数点后的位数小于 4,不进行转换,直接返回原字符串 // if (res.length - 1 - pointIndex < 4) { // return res // } // // 如果负数的整数部分大于 0 // if (Number(res[1]) > 0) { // // 如果 numberDigit 未定义或者为 0,不进行转换,直接返回原字符串 // if (!String(numberDigit) || String(numberDigit) === '0') { // return res // } // else { // // 否则对原数值进行四舍五入处理 // return useRound(value, numberDigit) // } // } // } // // 用于记录第一个非零小数位的索引 // let digitsIndex = 0 // // 从小数点后的位置开始遍历字符串,找到第一个非零数字的索引 // for (let i = pointIndex + 1; i < res.length; i++) { // if (Number(res[i]) > 0) { // digitsIndex = i // break // } // } // // 如果没有找到非零小数位,不进行转换,直接返回原字符串 // if (digitsIndex === 0) { // return res // } // // 提取非零小数位及后面的数字,进行四舍五入处理 // const digitsNumber = useRound(`${res[digitsIndex]}.${res.substring(digitsIndex + 1, res.length)}`, notationDigit) // // 拼接最终的科学计数法字符串,考虑正负号和指数部分 // return `${res[0] === '-' ? '-' : ''}${digitsNumber}e-${digitsIndex - pointIndex}` // } // else { // // 如果不是小数,不进行转换,直接返回原字符串 // return res // } // } // else { // console.log('--------------------'); // // 如果不小于转换标准,不进行转换,直接返回原字符串 // return res // } // } /** * 根据自定义规则将输入值转换为科学计数法或按要求保留有效数字,若已是科学计数法则直接返回 * @param {unknown} value - 输入的值,可以是任意类型 * @param {number} integerDigits - 判断是否转换为科学计数法的整数部分最小位数 * @param {number} decimalDigits - 判断是否转换为科学计数法的小数部分最小位数 * @returns {number | string} - 若满足转换条件则返回科学计数法字符串,按要求保留有效数字,否则返回原数字或无法转换时返回原输入 */ export function useScientificNotation(value: unknown, integerDigits = 6, decimalDigits = 4): number | string { console.log('接收到的需要处理的数据', value) // 先将传入的值转换为字符串形式,方便后续判断是否为科学计数法 const valueStr = String(value) // 判断是否已经是科学计数法(包含 'e' 或 'E') if (valueStr.includes('e') || valueStr.includes('E')) { return valueStr } let num: number | string // 判断传入的值是否已经是数字类型 if (typeof value === 'number') { // 如果是数字类型,直接赋值给 num num = value } else { // 如果不是数字类型,尝试将其转换为数字 num = Number(value) // 检查转换后的结果是否为 NaN(非数字) if (isNaN(num)) { // 如果是 NaN,说明无法转换为数字,直接返回原输入值 return value as string } } // 当数值 > 1 或者 < -1 时,保留小数后 2 位有效数字 if (num >= 1 || num <= -1) { num = parseFloat(num.toFixed(2)) } // 当数值为 0.** 或者 -0.** 时,保留小数点后除 0 外的 3 位有效数字,转科学计数法,不管几位都要转 if (num > -1 && num < 1 && num !== 0) { const numStr = num.toString() let nonZeroIndex = 0 // 找到小数点后第一个非零数字的位置 for (let i = numStr.indexOf('.') + 1; i < numStr.length; i++) { if (numStr[i] !== '0') { nonZeroIndex = i break } } // 计算需要保留的小数位数 const precision = nonZeroIndex + 3 - (numStr.indexOf('.') + 1) num = parseFloat(num.toFixed(precision)) num = num.toExponential(2) } // // 将数字转换为字符串,方便后续拆分整数部分和小数部分 // const numStr = num.toString() // let integerPart: string // let decimalPart: string // // 检查数字字符串中是否包含小数点 // if (numStr.includes('.')) { // // 如果包含小数点,使用 split 方法按小数点分割字符串,并分别赋值给整数部分和小数部分 // [integerPart, decimalPart] = numStr.split('.') // } // else { // // 如果不包含小数点,说明是整数,将整个字符串赋值给整数部分,小数部分为空字符串 // integerPart = numStr // decimalPart = '' // } // console.log('------------------------integerPart', integerPart) // // 检查整数部分的长度是否大于等于指定的整数位数 或者 小数部分的长度是否大于等于指定的小数位数 // if (integerPart.length >= integerDigits || decimalPart.length >= decimalDigits) { // // 如果满足条件,将数字转换为科学计数法表示的字符串并返回,保留 2 位小数 // console.log('进行科学技术法的转换', num.toExponential(2)) // return num.toExponential(2) // } // 如果不满足条件,直接返回原数字 return num }