如何将包含科学记数法的字符串转换为正确的 Javascript 数字格式

How to convert a String containing Scientific Notation to correct Javascript number format

本文关键字:转换 Javascript 格式 数字 字符串 包含科      更新时间:2023-09-26

我有一个字符串e.g: "4.874915326E7"。将其转换为 javascript 数字格式的最佳方法是什么?(整数或浮点数)?如果我尝试 parseInt(),最后的 E 将被忽略。

编辑:

这个答案似乎引起了一些混乱。 最初的问题是询问如何将字符串形式的科学记数法转换为数字(以便它可以用于计算)。 然而,找到这个答案的人似乎认为这是关于将javascript表示为科学记数法的数字转换为更像样的格式。 如果这实际上是您的目标(演示文稿),那么您应该将数字转换为字符串。 请注意,这意味着您将无法轻松地在计算中使用它。

原答案:

将其作为字符串传递给 Number 函数。

Number("4.874915326E7") // returns 48749153.26
Number("4E27") // returns 4e+27

将科学记数法中的数字转换为字符串:

这个问题最好用另一个问题来回答,但是从这个问题中,我个人喜欢使用的解决方案 .toLocaleString() .请注意,该特定解决方案不适用于负数。 为方便起见,这里有一个例子:

(4e+27).toLocaleString('fullwide', {useGrouping:false}) // returns "4000000000000000000000000000"

我有一个这样的值3.53048874968162e-09并且使用Number.toFixed(20)对我有用:

value = new Number('3.53048874968162e-09')
//[Number: 3.53048874968162e-9]
value.toFixed(20)
//'0.00000000353048874968'

尝试这样的事情

演示

Number("4.874915326E7").toPrecision()

您还可以使用字符串前面+符号来获取数字。

+"4.874915326E7" // == 48749153.26

前言

虽然其他答案是足够且正确的,以便能够正确解析字符串中的数字,但了解类型强制(在您的情况下为转换)如何至少在高级别工作是很有用的。

强制规则

有一些规则定义了在调用parseIntparseFloatNumber构造函数或一元运算符等实用程序时如何执行转换+

parseInt(<value>, [radix])功能:

  • 忽略前导空格 ( " 24" -> 24
  • 空字符串返回NaN
  • 第一个非数字字符完成解析 ( " 42answer" -> 42
  • 在上述规则下,小数位也完成解析

第三条规则正是为什么指数部分(ExponentPart由标准中定义的ExponentIndicatorSignedInteger组成)被忽略 - 一旦遇到e字符,解析就会停止,函数返回到目前为止解析的数字。事实上,它更早停止 - 当第一次遇到小数点时(请参阅最后一个规则)。

parseFloat()parseInt相同,除了:

  • 它解析第一个小数点
  • 忽略前导0(因此无法解析十六进制)

根据经验,在转换为"整数"时应使用parseIntparseFloat转换为"float"(请注意,它们实际上是同一类型)。

Number()构造函数和一元+

  • 对于布尔值 -> true1false0

  • 对于null -> 0(因为null是假的)

  • 对于undefined -> NaN

  • 对于数字:直通

  • 对于字符串:

    • 仅数字 [0-9] 字符,以数字或+-开头 -> 数字(整数)
    • 相同,但包含浮点数 -> 数字(浮点数)
    • 包含十六进制 -> 数字(整数)
    • 空字符串 -> 0
    • 所有其他情况 -> NaN
  • 对于对象,调用其valueOf()方法。如果结果为 NaN ,则调用toString()方法。在引擎盖下,对象被转换为基元,该基元被转换为数字。

  • 对于符号和 BigInts -> TypeError 被抛出

关于数字格式的说明

由于问题仍然吸引与格式有关的答案和评论(如接受的答案有效说明的那样),因此应该说明:

应用于编程时,"数字格式"有严格的含义:
数值的表示形式

"转换"也具有严格的类型转换含义(见标准)

ECMAScript 实现了双精度 64 位格式,这是它唯一的"格式"。该问题询问有关将字符串转换为数字格式的信息,因此答案应提供有关以下方面的信息:

如何将字符串转换为数字,因为该值表示电子表示法中的数字

引用

  1. ToNumber ECMAScript 标准中的抽象操作
  2. 关于这个主题和许多其他主题,我读过的最好的读物之一:Matt Frisbie的"Web 开发人员的专业Javascript"。
  3. 类型强制解释(博客文章)

对于整数,您可以使用 BigInt。对于非常大的数字不是很精确,但效果很好,我发现它是最简洁、最容易记住的选项:

BigInt(1e18).toString() => '1000000000000000000'
BigInt(1e36).toString() => '1000000000000000042420637374017961984'
BigInt(Math.round(4.874915326E7)).toString() => '48749153'

使用 MathJs 库对我来说效果最好,尝试了很多这些答案,但在某些情况下都没有正常工作。这非常有效。更多内容 https://mathjs.org/

解决方案,添加 MathJS,然后像这样调用它:

<script src="https://cdn.jsdelivr.net/npm/mathjs@8.0.1/lib/browser/math.js"  crossorigin="anonymous"></script>
    
    function toPlainString(num) {
        return math.format(num,  {notation: 'fixed'});
    }

对我来说,简单/最安全的方法是:

export function stringifyNumber(num: number) {
    const [integer, decimals] = num.toString().split(".");
    if (decimals) {
        return BigInt(integer).toString() + "." + BigInt(decimals).toString();
    }
    return BigInt(integer).toString();
}
function convertScientificToDecimal(number) {
  const decimalPlaces = -Math.floor(Math.log10(Math.abs(number)));
  return Number(number.toFixed(decimalPlaces));
}
const numberInScientificNotation = 3.5209577676952493e-10;
const decimalNumber = convertScientificToDecimal(numberInScientificNotation);
console.log(decimalNumber); // 0.0000000004