繁体   English   中英

在数字上保留尾随或前导零

[英]Keep trailing or leading zeroes on number

是否可以在 javascript 中的数字上保留尾随或前导零,而不使用例如字符串?

const leading  = 003;                 // literal, leading
const trailing = 0.10;                // literal, trailing
const parsed   = parseFloat('0.100'); // parsed or somehow converted

console.log(leading, trailing, parsed); // desired: 003 0.10 0.100

这个问题经常被问到(现在仍然是) 但我没有一个让我觉得很舒服的链接(我错过了吗?)。

完全类似地,将输入数字文字的表示形式的任何其他方面保持为,尽管几乎没有经常被问到:

console.log(0x10); // 16 instead of potentially desired 0x10
console.log(1e1);  // 10 instead of potentially desired 1e1

为了消除歧义,这与以下主题无关,我将添加其中一些链接,因为它们可能也很有趣:

不。 number不存储有关其输入或解析的表示形式的信息。 它只与它的数学价值有关。 也许重新考虑使用string


为了理解原因,让我们从数学意义上讨论数字,以及它们的表示/名称(虽然 javascript 的number并不完全等同于数学数字,但其意图仍然是表现得像一个)。 如果我不得不猜测,大部分的困惑来自于人们以某种方式将一个数字与他们输入的单一表示联系得太紧密,假设它们将紧密耦合。

https://en.wikipedia.org/wiki/Number

数字是用于计数、测量和 label 的数学 object。 原始示例是自然数 1、2、3、4 等。 [1]数字可以用数字词表示。 更普遍的是,单个数字可以用符号表示,称为数字。 例如,“5”是代表数字五的数字。

该摘录已经使用表示/名称(“数字单词”、“数字”或“符号”)来表达示例数字。 对于本主题,将数字视为“数学对象”将很有用。 重要的是要注意,例如在构造实数 ℝ时,包括其加法的中性元素,这些元素最初没有名称。 我们给这些对象命名,以便更好地讨论它们,例如前面提到的中性元素的“0”。

大多数程序员都知道不止一种表示数字的方法:例如十进制1 10 、十六进制0xA (或“A 16 ”)、二进制0b1010 (或“1010 2 ”),还有10.010.00 2 虽然数学 object 在某种意义上一直存在(参见哲学问题“数学是发明还是发现?”),但我们给它取什么名称或表示是任意的。 作为另一个例子, 0的词在许多语言中是不同的,例如“零”、“空”、“零”/“〇”、...

这意味着数学数字的表示/名称是多对一的关系,因此不可逆:您可以从某个表示/名称中获取数字,但另一方面,您不知道该选择哪个。 例如0.10.10代表相同的数字。 给定这个数字,如何决定拿哪一个来显示它? 甚至可能是三分之一。 在大多数情况下,对于返回的方式,构建可能表示之一的算法被任意选择为默认值。 再次注意,即使这个默认值也不能“保持”前导或尾随零,因为它只有一个数学值可以使用,没有关于它来自什么或来自哪里的信息。

到目前为止,我们讨论了数学意义上的数字。 虽然它在概念上应该足够了,但要理解潜在的问题,让我们详细说明这与 javascript 的numberconst x = 0; typeof x === 'number' )的关系。 Javascript 使用 IEEE754-2019 float64作为number 3 NaN或带符号的零这样的细节,没有两个不同的值代表相同的数学数字4 从一个number值,我们得到它所代表的数学值,但没有味道或附加信息,可用于确定某些所需的表示。 根据 IEEE754-2019 6 ,当评估源代码5并遇到数字文字时,引擎会将文字表示的数学值(注意规范实际上使用“数学值”)转换为 64 位值。 这意味着有关代码中原始表示的任何信息都将丢失7

总之,当试图保留有关数字的某些表示的信息时(包括前导零或尾随零,无论它是写成十进制、十六进制等), number不是一个好的选择。 对于如何实现默认以外的一些特定表示,不需要访问最初输入的文本(例如填充到一定数量的数字),还有许多其他问题/文章,其中一些已经链接。


[1]:十进制通常是默认值。 因此,编写这样一个不带任何前缀、下标后缀(“10 10 ”)或其他元格式来标识格式的表示形式,意味着十进制。

[2]:还有一个问题,和主题有些无关。 Javascript 以前使用八进制表示法,前缀为“0”。 这意味着, 003被解析为八进制,并将进入严格模式。 同样, 010 === 8 (或在严格模式下抛出),请参阅为什么 JavaScript 将数字视为八进制,如果它有一个前导零

[3]: Javascript 也有BigInt ,但是虽然它在内部使用了不同的格式,但推理完全相似。

[4]:为了转换任何数学值(例如0.1 ),会发生某种舍入到最接近的可表示值。 换句话说,IEEE754-2019 float64 表示的数学值(甚至文字)是多对一的关系,例如1.00000000000000001 === 1.00000000000000002 ,两者都导致相同的表示。

[5]:例如 V8 会在评估之前转换为字节码,已经交换了文字。 唯一相关的是,在我们对它做任何事情之前,信息就丢失了。

[6]:这是一个简化。 从 javascript 观察时,只要保证它们在任何方面都像 IEEE754-2019 float64 一样,引擎就可以在内部使用其他格式(并且这样做,例如节省空间/时间)。

[7]: Javascript 提供了对代码本身进行操作的能力(例如Function.prototype.toString ),我不会在这里过多讨论。 自己解析代码并存储表示是一种选择,但与number的工作方式无关(您将在代码上操作string )。 此外,我没有立即看到任何理智的理由这样做,而不是替代方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM