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

74

我有一个字符串 例如:"4.874915326E7"。如何将其转换为JavaScript数字格式(整数或浮点数)?如果我尝试使用parseInt()函数,那么末尾的E会被忽略。


这通常被称为科学计数法(有时称为科学E记数法,但无论如何...) - Damien_The_Unbeliever
9个回答

103

编辑:

这个答案似乎引起了一些混淆。原问题是问如何把表示为字符串的科学计数法转换成数字(以便用于计算)。然而,很多人找到这个答案似乎认为它是关于将被javascript表示为科学计数法的数字转换为更具可呈现性的格式。如果你的目标确实是这样(表现),那么你应该将数字转换为字符串。请注意,这意味着你将无法像使用数字那样轻松地进行计算。

原始回答:

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

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

将科学计数法表示的数字转换为字符串:

这个问题最好通过另一个问题来回答,但是我个人喜欢使用.toLocaleString()的解决方案。请注意,该特定解决方案不适用于负数。以下是一个示例以供参考:

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

8
我的不工作。 Number("1.7976931348623157e308") - The_ehT
1
@The_ehT,这对我有效。当我在控制台中运行该代码时,typeof Number("1.7976931348623157e308")返回"Number"。如果不使用typeof在控制台中运行它,则返回数字"1.7976931348623157e+308"。 - Joseph Marikle
2
@JosephMarikle 但我想要我的数字用标准记数法而不是科学计数法。 - The_ehT
@The_ehT 啊!这就有意义了。这个问题是关于如何将它转换为“JavaScript数字格式”,以便与其他数字一起使用,对数值执行数学运算。您想将您的转换为扩展格式,这需要一个字符串。尝试这个答案:https://dev59.com/7HHYa4cB1Zd3GeqPJDou?lq=1 - Joseph Marikle
谢谢回复。我可以这样转换,但是如果我这样做,有些数字会丢失。例如,我有一个递归函数,最后的答案是4.12345678e10,如果我将其转换为标准表示法,结果会变成41234567800,其中最后两个数字00实际上不是00。因此,最好有一种方法来防止转换为科学计数法或任何其他黑客方式。 - The_ehT
显示剩余10条评论

14

我有这样一个值 3.53048874968162e-09,使用 Number.toFixed(20) 对我很有帮助:

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

1
请考虑加上为什么它有效以及参考资料的解释,特别是当您将其添加到旧问题时(这样的答案将进入审查队列)。请注意,问题不是关于格式化表示数字的字符串,而是关于将其转换为数字格式(尽管由于问题的表述方式引起的混淆是可以理解的)。 - Oleg Valter is with Ukraine
此外,您不应该创建新的数字对象 new Number() 来执行类型转换,而是直接使用 Number()(将返回原始类型)。 - Oleg Valter is with Ukraine

11

尝试像这样:

Demo

Number("4.874915326E7").toPrecision()

4
不需要使用.toPrecision(),如果精度低于提供的字符串,它会添加科学计数法。 - Cees Timmerman
1
Number("2.2356434336665664e+51").toPrecision() 这个不起作用..请帮我纠正这个问题。 - BALAJI R

10
你可以在你的字符串前面加上加号+来得到一个数字。
+"4.874915326E7" // == 48749153.26

2
同样适用于变量,甚至是在字符串中:x="1e3"; ":"+(+x) 得到的结果是 :1000 - Cees Timmerman
+"1e20"之后无法工作,例如+"1e21"返回1e21 - BitOfUniverse

2

前言

虽然其他答案足够且正确,但为了能够正确地从字符串中解析数字,至少需要了解类型强制转换(在您的情况下是转换)的工作原理。

强制转换规则

当您调用像parseIntparseFloatNumber构造函数或+一元运算符这样的实用程序时,有一些规则定义了如何执行转换:

parseInt(<value>, [radix])函数:

  • 忽略前导空格(" 24" -> 24
  • 空字符串返回NaN
  • 第一个非数字字符结束解析(" 42answer" -> 42
  • 根据上述规则,小数点也会结束解析
第三条规则正是为什么指数部分(ExponentPart标准 中定义的 ExponentIndicatorSignedInteger 组成)被忽略 - 一旦遇到 e 字符,解析就会停止并返回已解析的数字。事实上,它甚至会在更早的时候停止 - 当第一个小数点被发现时(参见最后一条规则)。 parseFloat()parseInt 完全相同,除了:
  • 它首先解析小数点
  • 忽略前导的 0(因此无法解析十六进制)
作为经验法则,当转换为“整数”时应使用 parseInt,而当转换为“浮点数”时应使用 parseFloat(请注意,它们实际上是相同的类型)。 Number() 构造函数和一元运算符 +
对于布尔值:将true转换为1,将false转换为0 对于null:将其转换为0(因为null是假值)
对于undefined:将其转换为NaN 对于数字:保持不变
对于字符串:
  • 只包含数字[0-9]字符,以数字或+-开头 -> 数字(整数)
  • 同上,但包含浮点数 -> 数字(浮点数)
  • 包含十六进制 -> 数字(整数)
  • 空字符串 -> 0
  • 所有其他情况 -> NaN
对于对象:调用它们的valueOf()方法。如果结果是NaN,则调用toString()方法。在内部,对象被转换为基本类型,然后该基本类型被转换为数字。
对于符号和BigInts:抛出TypeError异常
数字格式注释:
由于问题仍然吸引着关于格式的回答和评论(正如被接受的答案所说),应该声明:
在编程中,“数字格式”有一个严格的含义:数值的表示形式。
“转换”也有一个严格的含义,即类型转换(参见standard)。
ECMAScript实现了双精度64位格式,这是它唯一的“格式”。该问题询问如何将字符串转换为数字格式,因此期望回答提供以下信息:
如何将字符串转换为数字,给定的值表示科学计数法中的数字。
参考资料
  1. ToNumber是ECMAScript标准中的抽象操作
  2. 关于这个主题以及其他许多主题,我阅读过的最佳读物之一是Matt Frisbie的《专业JavaScript开发人员》。
  3. 类型强制转换解释(博客文章

1

对于整数,您可以使用BigInt。对于非常大的数字不是非常精确,但完美地工作,并且我发现它是最简洁和易于记忆的选项:

BigInt(1e18).toString() => '1000000000000000000'
BigInt(1e36).toString() => '1000000000000000042420637374017961984'

BigInt(Math.round(4.874915326E7)).toString() => '48749153'

0

对我来说,使用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'});
    }

2
说实话,我不太喜欢导入整个库来解决可以用一行本地代码实现的问题的想法。这是我们编写大型低效应用程序的方式,应被视为不良实践。 - dudewad

0

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

export function stringifyNumber(num: number) {
    const [integer, decimals] = num.toString().split(".");
    if (decimals) {
        return BigInt(integer).toString() + "." + BigInt(decimals).toString();
    }
    return BigInt(integer).toString();
}

0
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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接