【问题标题】:Javascript: converting very large and very small numbers to a fixed human readbale stringJavascript:将非常大和非常小的数字转换为固定的人类可读字符串
【发布时间】:2020-11-14 00:43:04
【问题描述】:

我有以下函数,我认为可以将非常大的数字(例如 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 ...

【问题讨论】:

  • .toFixed() 的数字参数从 0 到 20。
  • 你可以试试.toPrecision()
  • 您也可以使用Math.ceil(Math.log10(n)) 之类的东西来获取您需要的(可能是负数)位数。
  • 请记住,JavaScript 数字是 base-2 浮点值,它们不能提供无限精度。
  • 问题是您要寻找的原材料实际上并不存在于数量中。对于大指数,不存在低端数字。只有 51 位二进制小数的空间,甚至连 16 位十进制数字都没有。

标签: javascript numbers


【解决方案1】:

对于您的“非常大”部分:

  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)
  }

对于您的“非常小的”部分(虽然这需要进行测试,但它适用于我的示例,但我没有经历过极端情况):

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

【讨论】:

    【解决方案2】:

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

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

    10n**24n; // 1000000000000000000000000n
    

    BigInts,是 Int,没有小数点。但它们也很大,因此您可以使用定点表示法,例如前一千位是整数部分,后一千位是小数部分(最大大小取决于可用内存)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-05
      • 2012-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-12
      • 2014-02-04
      相关资源
      最近更新 更多