Ich habe gerade eine Frage, die ich nicht beantworten kann.
Angenommen, Sie haben diese Schleifendefinition in Java:
while (i == i) ;
Was ist der Typ i
und der Wert von, i
wenn die Schleife keine Endlosschleife ist und das Programm nur einen Thread verwendet ?
Antworten:
Die API für Double.equals () gibt die Antwort aus: "Double.NaN == Double.NaN hat den Wert false". Dies wird in der Java-Sprachspezifikation unter " Gleitkommatypen, -formate und -werte " erläutert :
quelle
x == x
immer wahr sein. Warum sollte sich etwas nicht gleichstellen?null=null
ist null.NULL IS NULL
ist 1.Der Wert von
i
ist dann ungültig. "Keine Zahl".Nach einigem googeln fand ich heraus, dass Sie NaN (Not a Number) in Java haben können! Eine Gleitkommazahl ist also der Datentyp und der Wert ist NaN. Siehe hier
quelle
NaN ist nichts gleich, auch nicht sich selbst.
quelle
quelle
Ich bin nicht sicher, aber ich glaube, dass (i == i) keine atomare Operation in einem Multithread-Prozess ist. Wenn also der i-Wert zwischen den Pushs seines Werts geändert wird, um ihn auf dem Thread zu stapeln, der die Schleife ausführt, kann diese Bedingung sei falsch.
quelle
Da andere sagten, es sei NaN, wurde ich neugierig auf die offizielle (JDK 6) Implementierung von
Double.isNaN
und siehe:quelle
Stellen Sie sich Nan als Äquivalent einer Ausnahme vor, verwenden Sie jedoch einen magischen Wert innerhalb einer Berechnung. Da eine Berechnung fehlgeschlagen ist - z. B. Quadratwurzel eines Negativs, Teilen durch Null usw. - macht es keinen Sinn, sie mit irgendetwas anderem zu vergleichen. Wenn die Division durch Null ein Nan ist, entspricht sie schließlich der Quadratwurzel von -2 oder der Quadratwurzel von -3?
Nan ermöglicht eine Berechnung, die einen Schritt enthält, der eine ungültige Antwort zurückgibt, ohne zusätzliche Ausnahmen einzuführen. Um zu überprüfen, ob die Antwort ein Wert ist, testen Sie einfach über Float.isNan () o Äquivalent auf Nicht-Nandness (ist das Wort, wenn ich es nicht einsacke).
quelle
Ich würde hinzufügen
ebenso gut wie
Ein häufiger Trick bei solchen Fragen ist die Annahme, dass ich ein Int bin. Andere gängige Annahmen könnten sein: s ist ein String, x, y sind ein Double, ch ist ein Zeichen, b ist ein Byte usw. Wenn Sie eine Frage wie diese sehen, können Sie darauf wetten, dass 'i' nicht der erwartete Typ ist.
Eine ähnliche Frage ist; Dies schleift nie, was ist 'x'
Eine andere Frage, die ich sehr mag, ist: Diese Schleife ist eine Endlosschleife. Was sind die möglichen Werte von x? (: Ich zähle zwölf davon :)
quelle
Ich weiß, dass dies eine Java-Frage ist, aber die Frage für andere Sprachen in Betracht zu ziehen, ist faszinierend.
In C könnte ein einfacher Typ wie 'int' das Verhalten 'Beenden, bevor das Universum kalt wird' aufweisen, wenn 'i' als flüchtig deklariert wird (sodass der Compiler gezwungen wäre, für jede Iteration zwei Lesevorgänge von 'i' durchzuführen). und wenn 'ich' tatsächlich in Erinnerung wäre, wo etwas anderes es beeinflussen könnte. Dann würde die Schleife enden, wenn 'i' zwischen den beiden Lesevorgängen einer einzelnen Iteration wechselt. ( Hinzugefügt : ein möglicher Ort - in einem Mikrocomputer, an dem sich 'i' tatsächlich an der Adresse eines E / A-Ports befindet, möglicherweise verbunden mit einem Positionssensor. Es wäre plausibler, wenn 'i' eine Zeigervariable wäre ( ein Zeiger auf flüchtigen Speicher) und die Anweisung war '
while (*i == *i);
'.)Wie aus anderen Antworten hervorgeht, kann in C ++ der Operator '==' vom Benutzer angegeben werden, wenn ich einer benutzerdefinierten Klasse angehöre, sodass möglicherweise alles möglich ist.
Ähnlich wie bei NaN wäre in einer SQL-basierten Sprache die Schleife nicht unendlich, wenn der Wert von i NULL wäre. Jeder Nicht-NULL-Wert würde die Schleife jedoch unendlich machen. Dies ist eher wie bei Java, wo eine beliebige Zahl (im Gegensatz zu NaN) die Schleife unendlich macht.
Ich sehe keine praktische Verwendung des Konstrukts, aber es ist eine interessante Trivia-Frage.
quelle
Ich war überrascht, diese Lösung nicht zu sehen:
Versuchen Sie als Antwort auf einen Kommentar Folgendes auszuführen:
x sollte theoretisch immer gleich dem Arkussinus (sin (x)) sein, in der Praxis jedoch nicht.
quelle
x
, die genau das gleiche Ergebnis mit genau der gleichen Ungenauigkeit liefern sollte. Arcsin kann das Ergebnis einer Sünde nicht mit Gleitkommazahlen umkehren, da der übergebene Wertasin()
nicht genau ist. Daher ist das Ergebnis vonasin()
ungenau und machtx == asin(sin(x))
falsch. Außerdem "macht" arcsin eine sin-Operation nicht unbedingt "rückgängig" - die sin-Funktion kann für mehrere Werte von x das gleiche Ergebnis liefern, weshalbasin()
nur Zahlen zwischen -π / 2 und π / 2 zurückgegeben werden.Keine Endlosschleife, ein Thread :)
quelle
i == i
ist nicht atomar. Von einem solchen Programm bewiesen:Update Hier ist ein weiteres Beispiel für eine Endlosschleife (es werden keine neuen Threads erstellt).
quelle
while (i == i);
nie mehr ausgeführt.