为啥 parseInt(1/0, 19) 返回 18?
Posted
技术标签:
【中文标题】为啥 parseInt(1/0, 19) 返回 18?【英文标题】:Why does parseInt(1/0, 19) return 18?为什么 parseInt(1/0, 19) 返回 18? 【发布时间】:2012-07-05 15:24:00 【问题描述】:我在 JavaScript 中有一个烦人的问题。
> parseInt(1 / 0, 19)
> 18
为什么parseInt
函数返回18
?
【问题讨论】:
有趣。但为什么这对你来说是个烦人的问题?您是否必须以其他方式处理 Infinity?如果是这样,if
可能会有所帮助。
你到底做了什么,要求你使用以 19 为底的数字或除以零!?
当您对 JS 感到困惑时,只需返回 this quote 并记住整个该死的语言是在不到 10 天的时间内设计和实现的(根据设计者的说法)。跨度>
来自常见问题解答:“您应该只根据您面临的实际问题提出实际的、可回答的问题。”这实际上并不是您实际面临的“烦人问题”,而是一个不切实际的例子that's been floating around the internet forever。
python 做同样的事情:int('I', 19) == 18
【参考方案1】:
1/0
的结果是Infinity
。
parseInt
将其第一个参数视为字符串,这意味着首先调用Infinity.toString()
,生成字符串"Infinity"
。所以它的工作原理与您要求它将以 19 为底的 "Infinity"
转换为十进制一样。
以下是以 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。
【讨论】:
@mithunsatheesh 试试parseInt('Infini',24)
。
@mithunsatheesh:因为以 24 为基数,n
也是一个有效数字,所以它实际上最终是 parseInt("Infini", 24)
。
为什么有人想用这种行为的语言“编程”,这超出了我的理解。
@FransBouma:JS 有它自己的美。真的,这里发生的任何事情在动态语言中都是不合理的。
@Jon:这个工件不是动态语言的结果;这是松散类型的结果。在严格类型的动态语言中,Infinity (float) 到 "Infinity" (string) 的隐式转换不会发生,以防止这种愚蠢。【参考方案2】:
这是事件的顺序:
1/0
评估为 Infinity
parseInt
读取 Infinity
并高兴地注意到 I
在基数 19 中是 18
parseInt
忽略字符串的其余部分,因为它无法转换。
请注意,您会得到任何基数 >= 19
的结果,但不会得到低于该基数的结果。对于基数 >= 24
,您将获得更大的结果,因为此时 n
成为有效数字。
【讨论】:
@Thilo BTW,这是什么原因,如果基数更大,为什么它可能停在 19?你知道,JS 可以解释的最伟大的基础是什么? @NordvindparseInt
将接受的最大基数是 36,因为英文字母表中有 26 个字母,并且约定是使用数字然后字母作为给定基数中的有效数字集.
关于要点#2,我可以建议将Infinity
更改为"Infinity"
...
@CJBS 正确,但在此之前缺少一个要点:parseInt
需要一个字符串作为其第一个参数,因此Infinity
被强制转换为"Infinity"
;这也应该是一个有序列表,而不是无序列表。但是接受的答案已经解释了一切……【参考方案3】:
补充以上答案:
parseInt 旨在将字符串解析为数字(线索在名称中)。在您的情况下,您根本不想进行任何解析,因为 1/0 已经 是一个数字,所以这是一个奇怪的函数选择。如果你有一个数字(你有)并且想将它转换为一个特定的基数,你应该使用 toString with a radix 来代替。
var num = 1 / 0;
var numInBase19 = num.toString(19); // returns the string "Infinity"
【讨论】:
【参考方案4】:补充以上答案
parseInt(1/0,19)
等价于parseInt("Infinity",19)
在基数 19 以内的数字 0-9
和 A-I
(or a-i)
是有效数字。因此,从“Infinity”它采用以 19 为底的 I
并转换为以 10 为底的 18
然后它尝试获取下一个字符,即n
,它在 base 19 中不存在,因此丢弃下一个字符(根据 javascript 将字符串转换为数字的行为)
所以,如果你写parseInt("Infinity",19)
OR parseInt("I",19)
OR parseInt("i",19)
,结果将是相同的,即18
。
现在,如果你写parseInt("I0",19)
,结果将是342
如I 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
【讨论】:
以上是关于为啥 parseInt(1/0, 19) 返回 18?的主要内容,如果未能解决你的问题,请参考以下文章
parseInt(8558968890839370929) 返回 8558968890839371000 ,为啥? [复制]
为啥 parseInt(8,3) == NaN 和 parseInt(16,3) == 1?
为啥 parseInt 使用 Array#map 产生 NaN?