JavaScript toString 为什么 -0 转换为 0?

问题描述 投票:0回答:3

当处理非整数的数字时,-0 与 0 是不同的数字。我正在用 JavaScript 构建一个计时器应用程序,显然在将分钟数转换为字符串时发现了困难的方法。

如果我们的分钟数是 -0 以外的任何其他数字,这样做就很好:

var minutes = (time_balance_s/60);
minutes = Math.sign(minutes) * Math.floor(Math.abs(minutes));
var seconds = time_balance_s - (minutes * 60);
seconds = Math.floor(Math.abs(seconds));
displayString = minutes+":"+seconds.toString().padStart(2, '0');

但是对于-0,负数被移除,使得我们在过去一分钟内的情况与我们还剩不到一分钟的情况无法区分。 (即如果还剩 21 秒,或者我们超时 21 秒,时间显示“0:21”)

我最初认为这与顺序或操作有关,并且“+”在 JavaScript 中有歧义。但即使这样也行不通:

var minutes = (time_balance_s/60);
minutes = Math.sign(minutes) * Math.floor(Math.abs(minutes));
var seconds = time_balance_s - (minutes * 60);
seconds = Math.floor(Math.abs(seconds));
displayString = minutes.toString()+":"+seconds.toString().padStart(2, '0');

经过大量搜索,我发现我必须做一个特例来处理这个问题,并使用一个特殊的 Object.is 运算符。这令人沮丧。

var minutes = (time_balance_s/60);
minutes = Math.sign(minutes) * Math.floor(Math.abs(minutes));
var seconds = time_balance_s - (minutes * 60);
seconds = Math.floor(Math.abs(seconds));
if (Object.is(minutes, -0)) {
  displayString = "-0"+":"+seconds.toString().padStart(2, '0');
} else {
  displayString = minutes.toString()+":"+seconds.toString().padStart(2, '0');
}

Mozilla 开发者文档 暗示这是故意的:

0 和 -0 都有“0”作为它们的字符串表示。 Infinity 返回“Infinity”,NaN 返回“NaN”。

我终于(过了一段时间)确实发现其他人在询问这种行为还有一个标准的链接。 util.inspect 的解决方案将不起作用,因为这是 JavaScript JavaScript 而不是 Node.js JavaScript。该标准似乎解释了应该如何处理数字,但似乎没有解释为什么要这样处理。

我想知道为什么JavaScript是这样的。为什么-0在转换为字符串时不保留为“-0”?这有历史原因吗?有很多关于它的讨论吗?

我知道它现在是一个标准,可能不会改变,但我觉得很奇怪,我很好奇是否有人知道。是否有一些优势案例让 -0 变成“0”是有益的?为什么在制定标准时没有更多的人争取 -0 成为“-0”?

javascript standards tostring zero negative-number
3个回答
0
投票

我认为大多数人会期望 [

0 * x === 0
=>
0 * x
0
的行为相同] 并希望尽可能少地考虑浮点数的微妙之处——在每种语言中,但甚至可能尤其是在 JavaScript 中,其中没有单独的整数类型。

至于你的代码,而不是乘以

Math.sign
,考虑将符号作为字符串:

var sign = time_balance_s < 0 ? "-" : "";
var totalSecondsD = Math.floor(Math.abs(time_balance_s));
var minutes = Math.floor(totalSecondsD / 60);
var seconds = totalSecondsD % 60;
displayString = sign+minutes+":"+String(seconds).padStart(2, '0');

-2
投票

因为 javascript 不知道 0 和 -0 是不同的。如果你会写 0 === -0 它返回 true 。您需要第四个相等性来确定它们在您的情况下是不同的 Object.is() 。这是区分 0 和 -0 的唯一方法,另一种方法是您已经提到的 infinity 和 -infinity 。没有任何其他方法可以比较 0 和 -0 ,它们对于 javascript 是相同的


-2
投票

您可以使用带有检查的函数并返回对齐的字符串。

const
    getString = v => v && v.toString()
        || Object.is(v, -0) && '-0'
        || Object.is(v, 0) && '0';

console.log(getString(-1));
console.log(getString(-0));
console.log(getString(0));
console.log(getString(1));

© www.soinside.com 2019 - 2024. All rights reserved.