Warum gibt parseInt (1/0, 19) 18 zurück?


853

Ich habe ein nerviges Problem in JavaScript .

> parseInt(1 / 0, 19)
> 18

Warum kehrt die parseIntFunktion zurück 18?


3
Interessant. Aber warum ist das ein nerviges Problem für Sie? Müssen Sie mit Infinity auf andere Weise umgehen? Wenn ja, ifkönnte ein helfen.
Thilo

254
Was zum Teufel hast du überhaupt gemacht, dass du entweder mit Basis-19-Zahlen oder mit Division durch Null arbeiten musstest?
Jack M

19
Wenn Sie über JS verwirrt sind, kehren Sie einfach zu diesem Zitat zurück und denken Sie daran, dass die gesamte verdammte Sprache in weniger als 10 Tagen entworfen und implementiert wurde (je nach der Person, die es getan hat).
Tyler

32
Aus den FAQ: "Sie sollten nur praktische, beantwortbare Fragen stellen, die auf tatsächlichen Problemen basieren, mit denen Sie konfrontiert sind." Dies ist eigentlich kein "nerviges Problem", mit dem Sie tatsächlich konfrontiert sind, sondern ein unrealistisches Beispiel , das schon immer im Internet herumschwirrt .
Jeremy Banks

2
Python macht das gleiche: int ('I', 19) == 18
oberhamsi

Antworten:


1292

Das Ergebnis von 1/0ist Infinity.

parseIntbehandelt sein erstes Argument als Zeichenfolge, was bedeutet, dass zuerst Infinity.toString()aufgerufen wird und die Zeichenfolge erzeugt wird "Infinity". Es funktioniert also genauso, als ob Sie es gebeten hätten, die "Infinity"Basis 19 in eine Dezimalzahl umzuwandeln .

Hier sind die Ziffern in Basis 19 zusammen mit ihren Dezimalwerten:

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

Als Nächstes wird parseIntdie Eingabe gescannt, "Infinity"um festzustellen, welcher Teil davon analysiert werden kann, und nach dem Akzeptieren des ersten angehalten I(da nin Basis 19 keine gültige Ziffer vorhanden ist).

Daher verhält es sich so, als hätten Sie aufgerufen parseInt("I", 19), was in der obigen Tabelle in Dezimalzahl 18 konvertiert wird.


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

112
@mithunsatheesh: Da in Basis 24 nauch eine gültige Ziffer ist, endet dies tatsächlich parseInt("Infini", 24).
Jon

36
Warum jemand in einer Sprache "programmieren" möchte, die sich so verhält, ist mir ein Rätsel.
Frans Bouma

45
@FransBouma: JS ist auf seine Weise schön. Und wirklich, kein Teil dessen, was hier passiert, ist in einer dynamischen Sprache unvernünftig.
Jon

59
@ Jon: Dieses Artefakt ist nicht das Ergebnis einer dynamischen Sprache. Es ist ein Ergebnis der losen Eingabe. In einer streng typisierten dynamischen Sprache würde die implizite Konvertierung von Infinity (float) in "Infinity" (string) nicht stattfinden, um diese Art von Albernheit zu verhindern.
Lie Ryan

225

Hier ist die Abfolge der Ereignisse:

  • 1/0 bewertet zu Infinity
  • parseIntliest Infinityund stellt glücklich fest, dass I18 in Basis 19 ist
  • parseInt ignoriert den Rest der Zeichenfolge, da sie nicht konvertiert werden kann.

Beachten Sie, dass Sie für jede Basis ein Ergebnis erhalten >= 19, jedoch nicht für Basen darunter. Für Basen erhalten >= 24Sie ein größeres Ergebnis, da es nzu diesem Zeitpunkt zu einer gültigen Ziffer wird.


@Thilo Übrigens, was wäre der Grund, warum es bei 19 aufhören könnte , wenn die Basis größer ist? Wissen Sie, was ist die größte Basis, die JS interpretieren kann?
Arnthor

4
@Nordvind Die größte Basis, parseIntdie akzeptiert wird, ist 36, da das englische Alphabet 26 Buchstaben enthält und die Konvention darin besteht, Ziffern und dann Buchstaben als Satz gültiger Ziffern in der angegebenen Basis zu verwenden.
Craig Citro

4
Auf Punkt 2 kann ich vorschlagen, Infinityzu "Infinity"...
CJBS

38

So ergänzen Sie die obigen Antworten:

parseInt soll Zeichenfolgen in Zahlen analysieren (der Hinweis befindet sich im Namen). In Ihrer Situation möchten Sie überhaupt keine Analyse durchführen, da 1/0 bereits eine Zahl ist, daher ist es eine seltsame Wahl der Funktion. Wenn Sie eine Zahl haben (was Sie tun) und diese in eine bestimmte Basis konvertieren möchten, sollten Sie stattdessen toString mit einem Radix verwenden.

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

13

Zu den obigen Antworten hinzufügen

parseInt(1/0,19) ist äquivalent zu parseInt("Infinity",19)

Innerhalb der Basis 19 Zahlen 0-9und A-I (or a-i)sind gültige Zahlen. Also, von der "Unendlichkeit" nimmt es Ivon Basis 19 und konvertiert zu Basis 10, die zu 18 wird. Dann versucht es, das nächste Zeichen zu nehmen, dhn das in der Basis 19 nicht vorhanden ist, und so die nächsten Zeichen zu verwerfen (gemäß dem Verhalten von Javascript beim Konvertieren von Zeichenfolgen in Zahlen )

Wenn Sie also parseInt("Infinity",19)ODER parseInt("I",19)ODER schreiben, ist parseInt("i",19)das Ergebnis dasselbe, dh 18.

Nun, wenn Sie schreiben , parseInt("I0",19)das Ergebnis wird sein , 342 wie 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

Ebenso parseInt("I11",19)wird sich ergeben6518

dh

  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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.