Por que parseInt (1/0, 19) retorna 18?

853

Eu tenho um problema irritante em JavaScript .

> parseInt(1 / 0, 19)
> 18

Por que a parseIntfunção retorna 18?

cebor
fonte
3
Interessante. Mas por que isso é um problema irritante para você? Você precisa lidar com o Infinito de outras maneiras? Se assim for, um ifpode ajudar.
Thile
254
Que diabos você estava fazendo isso exigiu que você trabalhasse com os números da base 19 OU com a divisão por zero !?
M
19
Quando você ficar confuso com o JS, volte para esta citação e lembre-se de que toda a maldita linguagem foi projetada e implementada em menos de 10 dias (de acordo com a pessoa que fez isso).
tylerl
32
No FAQ: "Você só deve fazer perguntas práticas e respondíveis com base nos problemas reais que enfrentar". Na verdade, esse não é um "problema irritante" que você realmente enfrenta; é um exemplo irreal que circula pela Internet para sempre .
Jeremy Banks
2
python faz a mesma coisa: int ('I', 19) == 18
oberhamsi 11/07/12

Respostas:

1292

O resultado de 1/0é Infinity.

parseInttrata seu primeiro argumento como uma string, o que significa que antes de tudo Infinity.toString()é chamado, produzindo a string "Infinity". Por isso, funciona da mesma forma como se você pedisse para converter"Infinity" na base 19 em decimal.

Aqui estão os dígitos na base 19, juntamente com seus valores decimais:

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

O que acontece a seguir é que parseIntvarre a entrada "Infinity"para descobrir qual parte dela pode ser analisada e para após aceitar a primeira I(porque nnão é um dígito válido na base 19).

Portanto, ele se comporta como se você tivesse chamado parseInt("I", 19), o que é convertido em decimal 18 pela tabela acima.

Jon
fonte
32
@mithunsatheesh Experimente parseInt('Infini',24).
Supr
112
@mithunsatheesh: Como na base 24 ntambém é um dígito válido, ele acaba fazendo parseInt("Infini", 24).
Jon
36
Por que alguém quer 'programar' em um idioma que se comporte assim está além de mim.
31412 Frans Bouma
45
@FransBouma: JS é bonito à sua maneira. E, na verdade, nenhuma parte do que acontece aqui é irracional em uma linguagem dinâmica.
Jon
59
@ Jon: esse artefato não é o resultado da linguagem dinâmica; é o resultado de digitação solta. Na linguagem dinâmica estritamente tipada, a conversão implícita de Infinity (float) em "Infinity" (string) não aconteceria, para evitar esse tipo de bobagem.
Lie Ryan
225

Aqui está a sequência de eventos:

  • 1/0 avalia como Infinity
  • parseIntInfinitye observa alegremente que Item 18 anos na base 19
  • parseInt ignora o restante da string, pois não pode ser convertido.

Observe que você obteria um resultado para qualquer base >= 19, mas não para as bases abaixo dela. Para bases >= 24, você obterá um resultado maior, pois nse torna um dígito válido nesse ponto.

Craig Citro
fonte
@ Thilo BTW, qual seria o motivo, por que pode parar aos 19, se a base for maior? Você sabe, qual é a melhor base JS que pode iterpret?
21712 Arnthor
4
@Nordvind A maior base parseIntaceita é 36, já que existem 26 letras no alfabeto inglês, e a convenção é usar dígitos e depois letras como o conjunto de dígitos válidos na base fornecida.
Craig Citro
4
No bala ponto # 2, pode Sugiro mudar Infinitypara "Infinity"...
CJBS
38

Para adicionar às respostas acima:

parseInt tem como objetivo analisar seqüências de caracteres em números (a pista está no nome). Na sua situação, você não deseja fazer nenhuma análise, já que 1/0 é um número, portanto, é uma escolha estranha de função. Se você tem um número (o que você faz) e deseja convertê-lo em uma base específica, use toString com uma raiz .

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

Para adicionar às respostas acima

parseInt(1/0,19) é equivalente a parseInt("Infinity",19)

Dentro dos números base 19 0-9e A-I (or a-i)são números válidos. Então, a partir do "Infinito", leva Ida base 19 e converte na base 10, que passa a 18. Então, tenta pegar o próximo caractern que não está presente na base 19, para descartar os próximos caracteres (conforme o comportamento do javascript de converter a string em número )

Então, se você escrever parseInt("Infinity",19)OR parseInt("I",19)OU, parseInt("i",19)o resultado será o mesmo, ie 18.

Agora, se você escrever parseInt("I0",19)o resultado será 342 como 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

Da mesma forma, parseInt("I11",19)resultará em6518

ie

  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
Imdad
fonte