【问题标题】:unexpected output in javascript when converting string to number将字符串转换为数字时javascript中的意外输出
【发布时间】:2017-10-15 17:05:28
【问题描述】:

在 MDN 中 this example on parseInt method

console.log(parseInt(4.7 * 1e22, 10)); // Very large number becomes 4
console.log(parseInt(4.7 * 1e20, 10)); //result is 470000000000000000000

或小于 20 的小数字给我预期的结果这是什么原因?

【问题讨论】:

  • 4.7 * 1e22 已经是一个整数。你为什么要再次将其解析为整数? parseInt 将第一个参数转换为字符串(因为它需要一个)并再次将其解析为整数。 4.7 * 1e22的实际结果是4.7e+22
  • 预期结果是什么?
  • 好的,我明白了,但在转换 4.7e+22 时也存在冲突,为什么这给 4 和 4.7e+2 给 470
  • 问题的答案,“为什么有些值可以准确表示而其他更大的数字,不是因为变量存储在内存中的分配方式。有一个最大值可以存储对于 JavaScript 中的 Number 类型,如在此处讨论 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…。这是评论而不是答案的原因是因为第二行输出的数字实际上比这大,我不知道为什么。我很感兴趣也可以听到答案。
  • 我的预期结果是 47000000000000000000000 而不仅仅是 4

标签: javascript numbers parseint type-conversion


【解决方案1】:

在基数为 10 的 20 位整数后失败。

你可以看看parseInt的描述:

由于某些数字在其字符串表示形式中包含 e 字符(例如 6.022e23),因此在用于非常大或非常小的数字时,使用 parseInt 截断数值会产生意想不到的结果。 parseInt 不应用作 Math.floor() 的替代品。

来自标准 ECMA 252 V 5.1 15.1.2.2 parseInt (string , radix)

第 13 步:

mathInt 为数学整数值,由 Z 以 radix-R 表示法表示,使用字母 AZ 和 az 用于值 10 到 35 的数字。(但是,如果 R 为 10 并且 Z 包含超过 20 个有效数字, 20 号之后的每个有效数字都可以替换为 0 数字,由实现选择;如果 R 不是 2、4、8、10、16,或 32,则 mathInt 可能是数学整数值的一个与实现相关的近似值,由 Z 以基数-R 表示法表示。)

...

注意

parseInt 可以仅将 string 的前导部分解释为整数值;它忽略任何不能被解释为整数表示法一部分的字符,并且没有给出任何此类字符被忽略的指示。

var x = 5.7 * 1e20;
console.log(x);
console.log(parseInt(x, 10));

x = 5.7 * 1e21;
console.log(x);
console.log(parseInt(x, 10));

【讨论】:

    【解决方案2】:

    在@Xufox 的帮助下

    console.log(parseInt(4.7 * 1e22, 10)); // Very large number becomes 4
    console.log(parseInt(4.7 * 1e20, 10)); //result is 470000000000000000000
    

    这里发生了什么步骤:

    • 计算完成 (4.7 * 1e20) 和 (4.7 * 1e22)
    • JavaScript 引擎的计算结果是stringified,因此可以将其传递给parseInt
    • 字符串被解析回一个数字
    • 终于记录下来了

    JavaScript 使用科学记数法截断每个超过 20 位的数字。这意味着计算的结果是:

    • 470000000000000000000
    • 4.7e22

    这些在传递给parseInt之前被字符串化:

    • “470000000000000000000”
    • “4.7e22”

    这些是字符串,而不是数字。 parseInt 现在将忽略第二个值中点之后的所有内容并返回 4

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-03
      • 2017-08-03
      • 2017-09-17
      • 2018-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多