You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaScript中比较以字符串表示的大十进制数?

原生JS/TS实现大十进制数比较(无需依赖库)

需求说明

需要实现函数getValuesGreaterThan(num: string | number, values: string[]),从字符串形式的大十进制数数组中筛选出大于指定数值的元素,要求完全避免精度丢失和类型转换异常。这些数值可能超出JavaScript Number类型的精度范围(比如整数部分超过2^53-1,或小数部分过长)。

实现思路

因为仅需比较大小,我们可以通过统一整数化的方式规避精度问题:

  • 拆分每个数字的整数部分与小数部分,统一为带小数点的标准格式
  • 统计所有待比较数字中最长的小数位数,将所有数字的小数部分补零至该长度,把十进制数转化为无小数的整数字符串
  • 借助BigInt类型转换整数字符串,直接进行大小比较(BigInt支持任意精度的整数运算,无精度丢失问题)

代码实现

function getValuesGreaterThan(num: string | number, values: string[]): string[] {
    // 将输入转为标准十进制字符串,处理整数、小数、科学计数法格式
    const normalizeNum = (n: string | number): string => {
        let str = typeof n === 'number' ? n.toString() : n.trim();
        // 处理科学计数法(如"1e+5"转为"100000")
        if (/e/i.test(str)) {
            const [coeff, expStr] = str.split(/e/i);
            const exp = parseInt(expStr, 10);
            const [intPart, fracPart = ''] = coeff.split('.');
            let newStr = intPart + fracPart;
            if (exp > 0) {
                newStr += '0'.repeat(Math.max(0, exp - fracPart.length));
            } else if (exp < 0) {
                newStr = '0.' + '0'.repeat(-exp - intPart.length) + newStr;
            }
            return newStr;
        }
        // 统一为带小数点的格式,方便后续拆分
        return str.includes('.') ? str : `${str}.`;
    };

    const targetStr = normalizeNum(num);
    // 收集所有待处理字符串,计算最长小数位数
    const allStrs = [targetStr, ...values].map(normalizeNum);
    const maxFracLength = Math.max(...allStrs.map(s => s.split('.')[1].length));

    // 将标准化后的字符串转为BigInt
    const toBigInt = (s: string): BigInt => {
        const [intPart, fracPart] = s.split('.');
        const paddedFrac = fracPart.padEnd(maxFracLength, '0');
        return BigInt(intPart + paddedFrac);
    };

    const targetBigInt = toBigInt(targetStr);

    // 筛选出大于目标值的元素
    return values.filter(val => {
        const valStr = normalizeNum(val);
        return toBigInt(valStr) > targetBigInt;
    });
}

// 测试示例
const testValues = [
    "1643764147.7500000000",
    "1643764147.7600000000382333388888",
    "1643764147.7700000000",
    "9999999999999999999999999999.12345678901234567890"
];

console.log(getValuesGreaterThan("1643764147.76", testValues));
// 输出: ["1643764147.7600000000382333388888", "1643764147.7700000000"]

边界情况说明

  • 负数处理:若需支持负数,可先判断符号:负数小于正数;同符号时,用上述方法比较绝对值大小即可。
  • 纯整数字符串:如"123"会被自动转为"123.",补零后正常处理。
  • 科学计数法输入:代码已兼容"1.23e+5"这类格式,会转换为标准十进制字符串后再处理。

内容的提问来源于stack exchange,提问作者Daniel Kaplan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 18:33:26