为什么parseInt(1/0,19)返回18?


853

我在JavaScript中遇到一个烦人的问题。

> parseInt(1 / 0, 19)
> 18

为什么parseInt函数返回18


3
有趣。但是,为什么这对您来说是一个烦人的问题?您是否需要以其他方式处理Infinity?如果是这样,if可能会有所帮助。
Thilo 2012年

254
您到底在做什么,这要求您使用以19为底的数字或除以零!
Jack M

19
当您对JS感到困惑时,只需回到这句话,并记住整个可恶的语言是在不到10天的时间内完成了设计和实现的(根据编写者的说法)。
tylerl 2012年

32
在常见问题解答中:“您仅应根据自己遇到的实际问题提出切实可行的问题。” 这实际上并不是您实际面临的“烦人的问题”,这是一个不切实际的例子,并且一直在互联网上流传至今
杰里米·班克斯

2
python做同样的事情:int('I',19)== 18
oberhamsi 2012年

Answers:


1292

的结果1/0Infinity

parseInt将其第一个参数视为字符串,这意味着首先Infinity.toString()被调用,生成字符串"Infinity"。因此,其工作原理与您要求将其以"Infinity"19为基数转换为十进制的方法相同。

以下是以19为底的数字及其十进制值:

Base 19   Base 10 (decimal)
---------------------------
   0            0
   1            1
   2            2
   3            3
   4            4
   5            5
   6            6
   7            7
   8            8
   9            9
   a            10
   b            11
   c            12
   d            13
   e            14
   f            15
   g            16
   h            17
   i            18

接下来发生的情况是parseInt扫描输入"Infinity"以查找可以解析的部分,并在接受第一部分后停止I(因为n这不是以19为底的有效数字)。

因此,它的行为就像您调用了一样parseInt("I", 19),该表通过上表转换为十进制18。


32
@mithunsatheesh尝试parseInt('Infini',24)
2012年

112
@mithunsatheesh:因为在24进制中n也是一个有效数字,所以它实际上结束了parseInt("Infini", 24)
2012年

36
为什么有人想用行为像这样的语言来“编程”,这超出了我的范围。
弗朗斯·布玛

45
@FransBouma:JS以自己的方式很漂亮。实际上,在动态语言中,这里发生的一切都不是不合理的。
2012年

59
@Jon:这种伪像不是动态语言的结果;这是打字错误的结果。在严格类型的动态语言中,不会发生Infinity(浮动)到“ Infinity”(字符串)的隐式转换,以防止这种愚蠢的行为。
Lie Ryan

225

这是事件的顺序:

  • 1/0 评估为 Infinity
  • parseInt读取Infinity并愉快地注意到I以19为底的18
  • parseInt 忽略字符串的其余部分,因为它无法转换。

请注意,您将获得任何基准的结果>= 19,但低于该基准的结果将不会。对于base >= 24,您会得到更大的结果,因为这n将成为有效数字。


@Thilo BTW,这是什么原因,如果基数更大,为什么它可能会停在19?您知道吗,Iterpret可以实现的最大基础JS是什么?
Arnthor

4
@Nordvind可接受的最大基数parseInt是36,因为英文字母中有26个字母,并且约定是使用数字,然后使用字母作为给定基数中的有效数字集。
Craig Citro 2012年

4
关于要点2,我是否建议更改Infinity"Infinity"...
CJBS

38

要添加以上答案:

parseInt旨在将字符串解析为数字(线索在名称中)。在您的情况下,您根本不需要进行任何解析,因为1/0 已经是一个数字,因此这是一个奇怪的功能选择。如果您有一个数字(要执行此操作),并且想要将其转换为特定的底数,则应改用toString和基数

var num = 1 / 0;
var numInBase19 = num.toString(19); // returns the string "Infinity"

13

添加到以上答案

parseInt(1/0,19) 相当于 parseInt("Infinity",19)

在基地19号0-9A-I (or a-i)是一个有效的数字。因此,从“ Infinity”开始,它取I底数为19,然后转换为底数10,后者变为18。然后尝试取下一个字符,即n不存在于底数19的字符,因此丢弃下一个字符(根据javascript将字符串转换为数字的行为) )

因此,如果您编写parseInt("Infinity",19)OR或 parseInt("I",19)OR parseInt("i",19)的结果将相同,即18

现在,如果你写parseInt("I0",19)的结果将是342I X 19 (the base)^1 + 0 X 19^0 = 18 X 19^1 + 0 X 19^0= 18 X 19 + 0 X 1 =342

同样,parseInt("I11",19)将导致6518

  18 X 19^2  +   1 X 19^1   +  1 X 19^0
= 18 X 19^2  +   1 X 19^1   +  1 X 19^0
= 18 X 361   +   1 X 19     +  1 X 1
= 6498  +  19  +  1
= 6518
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.