Javascript:将非常大和非常小的数字转换为固定的人类可读字符串

Javascript: converting very large and very small numbers to a fixed human readbale string

我有以下函数,我认为它可以将非常大的数字(例如 1e+24 和非常小的数字(例如 1e-18)转换为固定字符串,例如 10000000000000000000000000:

    convertExponentialToDecimal (exponentialNumber) {
      // Sanity Check - i.e., is it exponential number?
      const str = exponentialNumber.toString()
      if (str.indexOf('e-') !== -1) {
        const exponent = parseInt(str.split('-')[1], 10)
        return exponentialNumber.toFixed(exponent)
      }
      if (str.indexOf('e+') !== -1) {
        const exponent = parseInt(str.split('+')[1], 10)
        return exponentialNumber.toFixed(exponent)
      }
      return exponentialNumber
    }

但是,对于非常大的数字 - 该过程似乎不起作用...

即,1e+24 的转换产生 1e+24,但 1e-18 产生 0.000000000000000001,如预期的那样。

任何人都可以发现明显的问题,或者对这种情况有任何指示甚至他们自己的工作解决方案...

如果这是任何见解 - 它适用于任何小于 1e+21 的东西...

你的 'very large' 部分:

  if (str.indexOf('e+') !== -1) {
    let [a,b] = str.split('+')
    a = a.slice(0,-1)
    if (a.indexOf('.') !== -1) {
        b = parseInt(b) - (a.length - a.indexOf('.') -1)
    }
    return a.replace('.','')+"".padEnd(b,0)
  }

对于你的 'very small' 部分(虽然这需要测试,但它适用于我的例子,但我没有经历极端情况):

if (str.indexOf('e-') !== -1) {
  const [a,b] = str.split('-')
  return '0.'+a.slice(0,-1).padStart(b,0).replace('.','')
}

数字类型是 IEEE754 浮点数,幕后双精度,它没有足够的精度来表示 1e24 位数字。如果您想避免将数字视为字符串,请考虑 BigInt 数据类型。

有带 n 后缀的 BigInt 文字,它们不支持指数表示法,但幸运的是它们支持 **。对于大数字,您可以使用

10n**24n; // 1000000000000000000000000n

BigInts,是Int,没有小数点。但它们也很大,所以你可以负担得起定点符号,比如前千位是整数部分,后千位是小数部分(最大大小取决于可用内存)。