如何在JavaScript中检查指数值

3
我正在从CSV文件中流式传输数据,并将某些值推送到数组中。其中一些值非常大,可能会作为指数值导出(例如5.02041E+12),而有些可能是普通值。 我想编写一个if语句来检查这些值是否为指数值,如果是,则将它们传递给一个函数,将它们转换为'正常'数字(例如5020410000000)。有没有快速的方法来实现这个功能?
(这些值将被传递给API调用,因此需要将它们转换为“正常”值)
这可能看起来像这样的示例:
valueOne = 5.02041E+12;
valueTwo = 1234;

if (valueOne.isExponential) {
  **pass to converting function**
}

//Output = 5020410000000

if (valueTwo.isExponential) {
  **pass to converting function**
}

//Output = 1234 (unchanged)

我希望数组中的所有值都是“正常”值(即不是指数形式)。


请提供一个样例输入。 - Jonas Wilms
@JonasWilms 刚刚编辑 - 希望这能增加一些清晰度。 - Caleb Whittington
更简单的做法是不进行检查,而是显式地表示“所有”值的“正常”形式。 - MBo
执行 console.log(valueTwo) 然后就会有惊喜。 - Jonas Wilms
@MBo 的问题是,如果将非指数值传递给我的转换函数,该函数会将它们转换为“正常”值并导致出错。我认为添加一个简单的指数值检查比重构我的转换函数更容易。 - Caleb Whittington
3个回答

1
数字就是数字,值为 5.02041E+125020410000000 在内部没有区别:

// values in code:
var withe=5.02041E+12;
var withoute=5020410000000;
console.log(withe,"?=",withoute,withe===withoute);

// values parsed from strings:
var stringwithe="5.02041E+12";
var stringwithoute="5020410000000";
var a=parseFloat(stringwithe);
var b=parseFloat(stringwithoute);
console.log(a,"?=",b,a===b);

并且您也可以看到,当您简单显示一个数字时,它默认不会使用科学计数法,实际上您需要通过使用 toExponential() 来请求它。
您可能要担心的一件事是Number的内部精度。它有一个方法isSafeInteger()和各种字段,如MAX_SAFE_INTEGER。超过该值可能导致意外结果:

var a=Number.MAX_SAFE_INTEGER;
console.log("This is safe:",a,Number.isSafeInteger(a));
a++;
for(var i=0;i<5;i++)
  console.log("These are not:",a++,Number.isSafeInteger(a));

所以循环不能再增加a,因为这里没有数字9007199254740993。在9007199254740992之后存在的下一个数字是9007199254740994。但是这些数字比问题中的5020410000000大1000倍以上。

这是非常有用的信息,我会在以后牢记在心,谢谢。但是,我不能将我的值以指数形式呈现,因为我将使用这些值进行 API 调用。 - Caleb Whittington
@CalebWhittington 然而,我不能将我的值以指数形式存在,因为我将使用这些值进行API调用 - 你不会的,这也可以从控制台日志中看出(你点击了“运行代码段”按钮吗?)。你的问题实际上不存在。如果你不相信代码片段,请尝试在JavaScript控制台中编写5.02041E+12.toString()toPrecision()实际上还有另一个用途,请查看文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision - tevemadar

0

你可以在每个数字上使用 toPrecision 并确保它转换

const valueOne = 5.02041E+12;
const valueTwo = 1234;

const precisionValueOne = valueOne.toPrecision(); // "5020410000000"
const precisionValue2 = valueTwo.toPrecision(); // "1234"

然后,您可以选择将其转换为数字:

sanitizedValueOne = Number(precisionValueOne); // 5020410000000
sanitizedValueTwo = Number(precisionValueTwo); // 1234

很高兴听到这个消息!请随意将其标记为已接受答案,以便其他前来查看的人。 - silicakes
阅读你链接的内容:如果省略了精度参数,则行为类似于Number.prototype.toString() - 这正是你正在做的事情。 - tevemadar
让我们暂且不谈解释。 这是我的想法:手头的问题与所表述的问题有些不同:OP试图以某种方式表示数字,而不是在其上执行计算。使用未带参数的toPrecision可以达到最初的目标,但我还猜测他可能需要稍后重新格式化它。使用带有参数的toPrecision可以实现这个目标,而不改变方法,这就是为什么避免使用toString似乎是合乎逻辑的步骤。 - silicakes

0

对于 E+ 和可能的 E- 进行 RegExp 匹配

你开始的“数字”必须是文本,但你也应该进行一些合理性检查。 在尝试任何基于数学的转换之前,最好检查它是否大于 MaxInt。


你不能使用正则表达式匹配数字,并将其转换为字符串会丢失E匹配器。 - silicakes
@silicakes 要么这些是JS中的Number,要么它们是文本。如果它们是Number,则不需要进行转换... - MikeB

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