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

ceb*_*bor 849 javascript parseint

我在JavaScript中遇到了烦人的问题.

> parseInt(1 / 0, 19)
> 18
Run Code Online (Sandbox Code Playgroud)

为什么要parseInt回来18

Jon*_*Jon 1288

结果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
Run Code Online (Sandbox Code Playgroud)

接下来发生的是parseInt扫描输入"Infinity"以找到它的哪个部分可以被解析并在接受第一个之后停止I(因为n它不是基数19中的有效数字).

因此它的行为就像你调用了一样parseInt("I", 19),它被上面的表转换为十进制18.

  • @mithunsatheesh:因为在24`n`中也是一个有效的数字,所以它实际上最终做了`parseInt("Infini",24)`. (112认同)
  • @Jon:这个工件不是动态语言的结果; 这是松散打字的结果.在严格类型的动态语言中,不会发生Infinity(float)到"Infinity"(字符串)的隐式转换,以防止这种愚蠢. (59认同)
  • @FransBouma:JS以自己的方式很漂亮.实际上,这里发生的事情的一部分在动态语言中是不合理的. (45认同)
  • 为什么有人想用一种表现得像这样的语言"编程"超出我的想法. (36认同)
  • @mithunsatheesh尝试`parseInt('Infini',24)`. (32认同)
  • 那么为什么parseInt(1/0,24)给了我151176378? (12认同)
  • @Tadeck:是的,因为我们喜欢JavaScript,注意它总是学习新东西:) +1 (9认同)
  • `parseInt`用于解析字符串,而不是调用`toString`的任意对象.传入`Infinity`(不是字符串)并将其转换为"Infinity"的能力实际上是一种非显而易见的隐式转换. (8认同)
  • @mattdeboard:我同意这是令人惊讶的,但不同意这是不合理的.每个决定都有利有弊; 对我来说,与IEE 754的协议是一个比非同意的非程序员的期望更合意的财产.开发人员已经接受过培训,即使计算机系统的模型与更广泛接受的模型不同,因为它们具有特定的工 我不希望*每个人*同意这个POV,但我也不认为把它称为斯德哥尔摩综合症是公平的. (8认同)
  • @LieRyan这不是隐含的.`parseInt`通过在其上调用`ToString`显式地将要解析的参数转换为字符串.什么是"无限"的正确字符串表示?"无限"对我来说似乎很合理.但是在任何地方都没有隐含的转换. (6认同)
  • @Jon:这是一种非显而易见且令人惊讶的行为,与JS是一种"动态语言"无关.它需要知道IEEE浮点标准任意将1/0定义为正无穷大而不是(更广泛接受,明显且不令人惊讶)未定义的值.我相信JS是一种很好的语言,但是这种合理的行为就像斯德哥尔摩综合症一样. (6认同)
  • 作为一名物理学家(或数学家),我假设`x/0`返回'undefined`,而不是'Infinity' - 就像mattdeboard所说的那样. (2认同)
  • @munchybunch - 你说自己"`parseInt`意在解析一个字符串",实际上它名称的"解析"部分暗示(并且所有声誉良好的JS引用状态),所以如果有人故意传递一个_not_的参数如果他们没有得到他们期望的结果,他们真的不应该太惊讶. (2认同)
  • 是不是"愚蠢"的一部分,"parseInt"愿意解析一个参数,其中只有一个前缀是给定基数中的有效数字?当输入在数字前缀后面有垃圾时,它不会报告错误和/或返回"undefined",而是忽略它.不幸的是,这很常见; PHP做同样的事情,就像C的`atoi()`和类似的函数一样. (2认同)

Cra*_*tro 224

这是事件的顺序:

  • 1/0 评估为 Infinity
  • parseInt阅读Infinity并愉快地记下I基数19中的18
  • parseInt 忽略字符串的其余部分,因为它无法转换.

请注意,您将获得任何基础的结果>= 19,但不会获得低于该基数的基数.对于基数>= 24,您将获得更大的结果,因为n在该点变为有效数字.

  • +1.除了基地> 19,它可能不会停留在我. (26认同)
  • @Nordvind最大的基础`parseInt`将接受36,因为英文字母中有26个字母,并且约定是使用数字然后字母作为给定基数中的有效数字集. (4认同)
  • 在子弹点#2上,我可以建议将"无限"改为"无限"`...... (4认同)

kyb*_*kos 37

要添加上述答案:

parseInt旨在将字符串解析为数字(线索在名称中).在你的情况下,你根本不想做任何解析,因为1/0 已经是一个数字,所以这是一个奇怪的功能选择.如果您有一个数字(您这样做)并希望将其转换为特定基数,则应使用带有基数的toString.

var num = 1 / 0;
var numInBase19 = num.toString(19); // returns the string "Infinity"
Run Code Online (Sandbox Code Playgroud)


Imd*_*dad 13

添加到上面的答案

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

基数为19的数字0-9, A-I (or a-i)是有效数字.因此,从"无限"取出I基数19并转换为基数10变为18然后它尝试获取下一个字符,即n基数19中不存在的字符,因此丢弃下一个字符(根据javascript将字符串转换为数字的行为) )

所以,如果你写parseInt("Infinity",19)OR parseInt("I",19)或者parseInt("i",19)结果会是相同的,即18.

现在,如果你写parseInt("I0",19)的结果将是342 as 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
Run Code Online (Sandbox Code Playgroud)