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?


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.


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.


@ 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"

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.