如何实现数字格式化:保留首个非零小数后4位有效数字
实现自定义数字格式化:保留第一个非零小数后的4位数字
问题描述
需要实现数字格式化功能,仅显示小数部分中第一个非零数字后的4位数字,而非固定4位小数。原自定义函数无法满足需求,会将极小数值格式化为0.0000,不符合预期。
原无效函数:
//Non working function for my purpose... function formatToFourDecimals(num) { return (Math.round(num * 10000) / 10000).toFixed(4); }
测试用例及预期结果:
const TOSHI_price_WETH = "0.000000010528483311"; // 目标:0.00000001052 const TOSHI_price_USD = "0.000018256390061274"; // 目标:0.00001825 const example1 = "0.000000010528483311"; //目标:0.00000001052 const example2 = "0.000018256390061274"; //目标:0.00001825 const example3 = "0.00035256565612116112161"; //目标:0.0003525 const example4 = "0.0121215121313131313131313"; //目标:0.01212 const example5 = "32.3232326262623"; //目标:32.3232
原函数输出结果(不符合预期):
0.0000 0.0000 0.0004 0.0121 $TOSHI price: 0.0000 WETH $TOSHI price USD: 0.0000 $
期望格式化规则:
- 将
0.000000010528483311格式化为0.00000001052 - 将
0.000018256390061274格式化为0.00001825 - 将
32.3232326262623格式化为32.3232
解决方案
实现思路
- 将输入字符串转换为数字,处理0和整数的特殊情况。
- 处理科学计数法格式的数字,转换为普通十进制字符串,避免解析错误。
- 定位小数部分第一个非零数字的位置,计算需要保留的总小数位数:前置零数量 + 1(第一个非零数字) + 4(后续四位)。
- 对数字进行四舍五入到指定小数位,再去除末尾多余的零和不必要的小数点,确保输出符合预期格式。
代码实现
function formatCustom(numStr) { const num = parseFloat(numStr); if (num === 0) return "0.0000"; // 处理整数情况 if (Number.isInteger(num)) return `${num}.0000`; // 处理科学计数法,转为普通十进制字符串 let str = num.toLocaleString('fullwide', { useGrouping: false }); if (str.includes('e')) { const [base, exponent] = str.split('e'); const exp = parseInt(exponent, 10); const absExp = Math.abs(exp); let [integerPart, decimalPart] = base.split('.'); decimalPart = decimalPart || ''; if (exp > 0) { // 正数指数:小数点右移 decimalPart = decimalPart.padEnd(absExp, '0'); integerPart += decimalPart.slice(0, absExp); decimalPart = decimalPart.slice(absExp); } else { // 负数指数:小数点左移 integerPart = integerPart.padStart(absExp, '0'); decimalPart = integerPart.slice(0, absExp) + decimalPart; integerPart = integerPart.slice(absExp); } str = `${integerPart}${decimalPart ? '.' + decimalPart : ''}`; } const [integerPart, decimalPart] = str.split('.'); if (!decimalPart) return `${integerPart}.0000`; // 找到小数部分第一个非零数字的索引 const firstNonZeroIndex = decimalPart.search(/[1-9]/); if (firstNonZeroIndex === -1) return `${integerPart}.0000`; // 计算需要保留的总小数位数 const totalDecimals = firstNonZeroIndex + 1 + 4; const rounded = num.toFixed(totalDecimals); // 去除末尾多余的零和可能的小数点 let result = rounded.replace(/\.?0*$/, ''); if (!result.includes('.')) { result += '.0000'; } return result; } // 测试用例验证 const TOSHI_price_WETH = "0.000000010528483311"; const TOSHI_price_USD = "0.000018256390061274"; const example1 = "0.000000010528483311"; const example2 = "0.000018256390061274"; const example3 = "0.00035256565612116112161"; const example4 = "0.0121215121313131313131313"; const example5 = "32.3232326262623"; console.log(formatCustom(example1)); // 输出:0.00000001052 console.log(formatCustom(example2)); // 输出:0.00001825 console.log(formatCustom(example3)); // 输出:0.0003525 console.log(formatCustom(example4)); // 输出:0.01212 console.log(formatCustom(example5)); // 输出:32.3232 console.log("$TOSHI price:", formatCustom(TOSHI_price_WETH), "WETH"); console.log("$TOSHI price USD:", formatCustom(TOSHI_price_USD), "$");
内容的提问来源于stack exchange,提问作者RasmonT
相关产品推荐
相关产品推荐

