Perché parseInt (1/0, 19) restituisce 18?


853

Ho un fastidioso problema in JavaScript .

> parseInt(1 / 0, 19)
> 18

Perché la parseIntfunzione ritorna 18?


3
Interessante. Ma perché questo è un problema fastidioso per te? Devi gestire Infinity in altri modi? In tal caso, ifpotrebbe essere d'aiuto.
Thilo,

254
Cosa diavolo stavi facendo che ti ha richiesto di lavorare con i numeri di base 19 o la divisione per zero !?
Jack M,

19
Quando sei confuso su JS, torna a questa citazione e ricorda che l'intero dannato linguaggio è stato progettato e implementato in meno di 10 giorni (secondo la persona che lo ha fatto).
Tylerl,

32
Dalle FAQ: "Dovresti solo porre domande pratiche e rispondenti in base ai problemi reali che affronti." Questo non è in realtà un "fastidioso problema" che in realtà affronti, è un esempio irrealistico che ha fluttuato su Internet per sempre .
Jeremy Banks,

2
python fa la stessa cosa: int ('I', 19) == 18
oberhamsi

Risposte:


1292

Il risultato di 1/0è Infinity.

parseIntconsidera il suo primo argomento come una stringa che significa innanzitutto che Infinity.toString()viene chiamato, producendo la stringa "Infinity". Quindi funziona come se gli avessi chiesto di convertire "Infinity"in base 19 in decimale.

Ecco le cifre nella base 19 insieme ai loro valori decimali:

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

Quello che succede dopo è che parseIntscansiona l'input "Infinity"per trovare quale parte può essere analizzata e si interrompe dopo aver accettato il primo I(perché nnon è una cifra valida nella base 19).

Pertanto si comporta come se si chiamasse parseInt("I", 19), che viene convertito in decimale 18 dalla tabella sopra.


32
@mithunsatheesh Try parseInt('Infini',24).
Supr

112
@mithunsatheesh: Perché nella base 24 nc'è anche una cifra valida, quindi finisce per farlo parseInt("Infini", 24).
Jon

36
Perché qualcuno voglia "programmare" in una lingua che si comporta in questo modo è al di là di me.
Frans Bouma,

45
@FransBouma: JS è bellissima a modo suo. E davvero, nessuna parte di ciò che accade qui è irragionevole in un linguaggio dinamico.
Jon

59
@Jon: questo artefatto non è il risultato di un linguaggio dinamico; è il risultato della digitazione libera. Nel linguaggio dinamico tipizzato rigorosamente, la conversione implicita di Infinity (float) in "Infinity" (stringa) non avverrebbe, per prevenire questo tipo di stupidità.
Lie Ryan

225

Ecco la sequenza degli eventi:

  • 1/0 valuta Infinity
  • parseIntlegge Infinitye nota felicemente che Iè 18 in base 19
  • parseInt ignora il resto della stringa, poiché non può essere convertita.

Tieni presente che otterrai un risultato per qualsiasi base >= 19, ma non per quelle inferiori. Per le basi >= 24, otterrai un risultato più grande, poiché na quel punto diventa una cifra valida.


@Thilo BTW, quale sarebbe la ragione, perché potrebbe fermarsi alle 19, se la base è maggiore? Sai, qual è la più grande base che JS può interpretare?
Arnthor,

4
@Nordvind La base più grande parseIntaccetterà è 36, poiché l'alfabeto inglese contiene 26 lettere e la convenzione prevede l'uso di cifre e quindi di lettere come l'insieme di cifre valide nella base indicata.
Craig Citro,

4
Al punto 2, suggerisco di passare Infinitya "Infinity"...
CJBS,

38

Per aggiungere alle risposte sopra:

parseInt ha lo scopo di analizzare le stringhe in numeri (l'indizio è nel nome). Nella tua situazione, non vuoi eseguire alcuna analisi poiché 1/0 è già un numero, quindi è una strana scelta di funzione. Se hai un numero (che fai) e vuoi convertirlo in una base particolare, dovresti invece usare toString con una radice .

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

13

Aggiungere alle risposte sopra

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

All'interno di base 19 numeri 0-9e A-I (or a-i)sono numeri validi. Quindi, dall '"Infinito" prende Idalla base 19 e si converte in base 10 che diventa 18 Quindi cerca di prendere il carattere successivo, cioè nche non è presente nella base 19, quindi scarta i caratteri successivi (secondo il comportamento di javascript di convertire la stringa in numero )

Quindi, se scrivi parseInt("Infinity",19)OR parseInt("I",19)OR parseInt("i",19)il risultato sarà lo stesso vale a dire 18.

Ora, se scrivi parseInt("I0",19)il risultato sarà 342 come 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

Allo stesso modo, parseInt("I11",19)si tradurrà in6518

vale a dire

  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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.