Ho appena ricevuto una domanda a cui non posso rispondere.
Supponiamo di avere questa definizione di loop in Java:
while (i == i) ;
Qual è il tipo ie il valore di ise il loop non è un loop infinito e il programma utilizza solo un thread ?
Ho appena ricevuto una domanda a cui non posso rispondere.
Supponiamo di avere questa definizione di loop in Java:
while (i == i) ;
Qual è il tipo ie il valore di ise il loop non è un loop infinito e il programma utilizza solo un thread ?
Risposte:
double i = Double.NaN;
L'API per Double.equals () specifica la risposta: "Double.NaN == Double.NaN ha il valore falso". Questo è elaborato nella specifica del linguaggio Java in " Tipi, formati e valori in virgola mobile ":
NaNè ordinata, in modo che il numerico operatori di confronto<,<=,>, e>=ritornofalsese uno o entrambi gli operandi sonoNaN. L'operatore di uguaglianza==ritornafalsese uno degli operandi lo èNaNe l'operatore di disuguaglianza!=ritornatruese uno degli operandi lo èNaN. In particolare,x!=xètruese e solo sexèNaN, e(x<y) == !(x>=y)saràfalsesexoyèNaN.
x == xdovrebbe essere sempre vero. Perché qualcosa non dovrebbe eguagliarsi?
null=nullè nullo. NULL IS NULLè 1.
Il valore di iè quindi Non valido. "Non un numero".
Dopo aver cercato su Google, ho scoperto che PUOI avere NaN (Not a Number) in Java! Pertanto, un numero di virgola mobile è il tipo di dati e il valore è NaN. Vedi qui
double i = Double.NaN;
NaN non è uguale a nulla, incluso se stesso.
float i = Float.NaN;
while(i == i) ;
System.out.println("Not infinite!");
Dato che altri hanno detto che è NaN, mi sono incuriosito dall'implementazione ufficiale (JDK 6) di Double.isNaN, ed ecco:
/**
* Returns <code>true</code> if the specified number is a
* Not-a-Number (NaN) value, <code>false</code> otherwise.
*
* @param v the value to be tested.
* @return <code>true</code> if the value of the argument is NaN;
* <code>false</code> otherwise.
*/
static public boolean isNaN(double v) {
return (v != v);
}
Pensa a Nan come l'equivalente di un'eccezione ma usa un valore magico all'interno di un calcolo. Perché un calcolo fallito - ad es. Radice quadrata di un negativo, divisione per zero ecc. - non ha senso confrontarli con qualsiasi altra cosa. Dopotutto se dividere per zero è un nan è equivalente alla radice quadrata di -2 o alla radice quadrata di -3?
Nan consente un calcolo che include un passaggio che restituisce una risposta non valida da completare senza introdurre eccezioni aggiuntive. Per verificare che la risposta sia un valore, è sufficiente provare la non nandness (è questa la parola se non la metto) tramite Float.isNan () o equivalente.
Vorrei aggiungere
float i = Float.NaN;
così come
double i = Double.NaN;
Un trucco comune in questo tipo di domande presuppone che io sia un int. Altre ipotesi comuni potrebbero essere s è una stringa, x, y sono un doppio, ch è un carattere, b è un byte ecc. Se vedi una domanda come questa puoi scommettere che 'i' non è il suo tipo previsto.
Una domanda simile è; Questo non gira mai, cos'è "x"
while(x == x && x != x + 0) { }
Un'altra domanda che mi piace è; Questo ciclo è un ciclo infinito, quali sono i possibili valori di x. (: Ne conto dodici) :)
while(x != 0 && x == -x) { }
So che questa è una domanda Java, ma considerare la domanda per altre lingue è intrigante.
In C, un tipo semplice come 'int' potrebbe esibire 'terminare prima che l'universo si raffreddi' comportamento se 'i' fosse dichiarato volatile (quindi il compilatore sarebbe costretto a fare due letture di 'i' per ogni iterazione) e se "i" fosse effettivamente in memoria dove qualcos'altro potrebbe influenzarlo. Quindi il ciclo terminerebbe quando 'i' cambiava tra le due letture di una singola iterazione. ( Aggiunto : un posto possibile - in un microcomputer in cui "i" si trova effettivamente all'indirizzo di una porta I / O, forse collegato a un sensore di posizione. Sarebbe più plausibile se "i" fosse una variabile puntatore ( un puntatore alla memoria volatile) e l'affermazione era ' while (*i == *i);'.)
Come evidenziato da altre risposte, in C ++, l'operatore '==' può essere fornito dall'utente se io sono di una classe definita dall'utente, quindi tutto potrebbe essere possibile.
Piuttosto come NaN, in un linguaggio basato su SQL, il ciclo non sarebbe infinito se il valore di i fosse NULL; tuttavia, qualsiasi valore non NULL renderebbe il ciclo infinito. Questo è piuttosto come Java, dove qualsiasi numero (al contrario di NaN) rende il ciclo infinito.
Non vedo il costrutto avere alcun uso pratico, ma è una domanda a quiz interessante.
Sono stato sorpreso di non vedere questa soluzione:
while (sin(x) == sin(x)) //probably won't eval to true
In risposta a un commento, prova a eseguire questo:
double x = 10.5f;
assert (x == asin(sin(x)));
x dovrebbe sempre essere uguale all'arcoseno (sin (x)) in teoria, ma in pratica non lo è.
x, che dovrebbe produrre lo stesso risultato esatto con la stessa esattezza. Arcsin non può invertire il risultato di un peccato con numeri in virgola mobile perché il valore passato a asin()non sarà esattamente preciso. Pertanto, il risultato di asin()sarà impreciso, rendendo x == asin(sin(x))falso. Inoltre, arcsin non necessariamente "annulla" un'operazione sin: la funzione sin può dare lo stesso risultato per più valori di x, motivo per cui asin()restituisce solo numeri compresi tra -π / 2 e π / 2.
i == inon è atomico. Provato da tale programma:
static volatile boolean i = true;
public static void main(String[] args) throws InterruptedException
{
new Thread() {
@Override
public void run() {
while (true) {
i = !i;
}
}
}.start();
while (i == i) ;
System.out.println("Not atomic! i: " + i);
}
Aggiorna Ecco un altro esempio di ciclo non infinito (non vengono creati nuovi thread).
public class NoNewThreads {
public static void main(String[] args) {
new NoNewThreads();
System.gc();
int i = 500;
System.out.println("Still Running");
while (i == i) ;
}
@Override
protected void finalize() throws Throwable {
super.finalize();
Thread.sleep(1000);
System.exit(0);
}
}
while (i == i);non verrà mai eseguito.