Właśnie dostałem pytanie, na które nie mogę odpowiedzieć.
Załóżmy, że masz tę definicję pętli w Javie:
while (i == i) ;
Jaki jest typ ii wartość, ijeśli pętla nie jest nieskończoną pętlą, a program używa tylko jednego wątku ?
Właśnie dostałem pytanie, na które nie mogę odpowiedzieć.
Załóżmy, że masz tę definicję pętli w Javie:
while (i == i) ;
Jaki jest typ ii wartość, ijeśli pętla nie jest nieskończoną pętlą, a program używa tylko jednego wątku ?
Odpowiedzi:
double i = Double.NaN;
API dla Double.equals () podaje odpowiedź: „Double.NaN == Double.NaN ma wartość false”. Jest to omówione w specyfikacji języka Java w sekcji „ Typy zmiennoprzecinkowe, formaty i wartości ”:
NaNjest nieuporządkowana, więc numeryczna operatory porównania<,<=,>, i>=powrotufalsejeżeli jeden lub oba argumenty sąNaN. Operator równości==zwraca,falsejeśli którykolwiek z operandów jestNaN, a operator nierówności!=zwraca,truejeśli którykolwiek z operandów toNaN. W szczególnościx!=xjesttruewtedy i tylko wtedyxNaN, gdy jest i(x<y) == !(x>=y)będzie,falsejeślixlubybędzieNaN.
x == xzawsze powinno być prawdą. Dlaczego nic nie miałoby się równać?
null=nullma wartość null. NULL IS NULLjest 1.
Wartość ijest wtedy nieprawidłowa. „To nie jest numer”.
Po pewnym googlowaniu odkryłem, że MOŻESZ mieć NaN (Not a Number) w Javie! Zatem liczba zmiennoprzecinkowa jest typem danych, a wartością jest NaN. Zobacz tutaj
double i = Double.NaN;
NaN nie jest równe niczemu, w tym sobie.
float i = Float.NaN;
while(i == i) ;
System.out.println("Not infinite!");
Ponieważ inni powiedzieli, że to NaN, zaciekawiło mnie oficjalne (JDK 6) wdrożenie Double.isNaNi oto:
/**
* 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);
}
Pomyśl o Nan jako o ekwiwalencie wyjątku, ale używaj wartości magicznej w obliczeniach. Ponieważ obliczenia nie powiodły się - np. Pierwiastek kwadratowy z wartości ujemnej, podzielenie przez zero itd. - nie ma sensu porównywać ich z czymkolwiek innym. W końcu jeśli dzielenie przez zero to nan, to czy jest to równoważne pierwiastkowi kwadratowemu z -2 czy pierwiastkowi kwadratowemu z -3?
Nan umożliwia obliczenia, które obejmują krok, który zwraca nieprawidłową odpowiedź do wykonania bez wprowadzania dodatkowych wyjątków. Aby sprawdzić, czy odpowiedź brzmi: po prostu przetestuj pod kątem braku nandness (czy to jest słowo, jeśli nie mam go w worku) za pomocą równoważnika Float.isNan ().
dodałbym
float i = Float.NaN;
jak również
double i = Double.NaN;
Typowa sztuczka w tego rodzaju pytaniach polega na założeniu, że ja jest int. Inne typowe założenia to: s to String, x, y to double, ch to char, b to byte itd. Jeśli zobaczysz takie pytanie, możesz się założyć, że „i” nie jest jego oczekiwanym typem.
Podobne pytanie brzmi; To nigdy się nie zapętla, co to jest 'x'
while(x == x && x != x + 0) { }
Kolejne pytanie, które bardzo mi się podoba, to; Ta pętla jest nieskończoną pętlą, jakie są możliwe wartości x. (: Naliczam ich dwanaście :)
while(x != 0 && x == -x) { }
Wiem, że jest to pytanie dotyczące języka Java, ale rozważenie tego pytania dla innych języków jest intrygujące.
W C prosty typ, taki jak „int”, mógłby się zakończyć, zanim wszechświat ostygnie, zachowanie, jeśli „i” zostało zadeklarowane jako zmienne (więc kompilator byłby zmuszony do wykonania dwóch odczytów „i” dla każdej iteracji) i jeśli „i” rzeczywiście było w pamięci, gdzie coś innego mogłoby na to wpłynąć. Następnie pętla zakończyłaby się, gdy „i” zmieniło się między dwoma odczytami jednej iteracji. ( Dodano : możliwe miejsce - w mikrokomputerze, gdzie „i” faktycznie znajduje się pod adresem portu I / O, być może podłączone do czujnika położenia. Byłoby bardziej prawdopodobne, gdyby „i” było zmienną wskaźnikową ( wskaźnik do pamięci ulotnej), a instrukcja brzmiała ' while (*i == *i);'.)
Jak pokazują inne odpowiedzi, w C ++ operator „==” może być dostarczony przez użytkownika, jeśli i należy do klasy zdefiniowanej przez użytkownika, więc wszystko może być możliwe.
Podobnie jak NaN, w języku opartym na SQL pętla nie byłaby nieskończona, gdyby wartość i wynosiła NULL; jednak każda wartość inna niż NULL sprawiłaby, że pętla byłaby nieskończona. Jest to raczej podobne do Javy, gdzie dowolna liczba (w przeciwieństwie do NaN) sprawia, że pętla jest nieskończona.
Nie sądzę, aby konstrukt miał jakiekolwiek praktyczne zastosowanie, ale jest to interesujące pytanie o ciekawostkę.
Byłem zaskoczony, że nie widziałem tego rozwiązania:
while (sin(x) == sin(x)) //probably won't eval to true
W odpowiedzi na komentarz spróbuj uruchomić to:
double x = 10.5f;
assert (x == asin(sin(x)));
x powinno zawsze być równe arcus sinus (sin (x)) w teorii, ale w praktyce tak nie jest.
x, która powinna dać dokładnie ten sam wynik z dokładnie taką samą niedokładnością. Arcsin nie może odwrócić wyniku grzechu za pomocą liczb zmiennoprzecinkowych, ponieważ przekazana wartość asin()nie będzie dokładnie dokładna. Dlatego wynik asin()będzie niedokładny i x == asin(sin(x))fałszywy. Ponadto arcsin niekoniecznie „cofa” operację sin - funkcja sin może dać ten sam wynik dla wielu wartości x, dlatego asin()zwraca tylko liczby między -π / 2 a π / 2.
i == inie jest atomowy. Udowodniony przez taki program:
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);
}
Aktualizacja Oto jeszcze jeden przykład nieskończonej pętli (nie są tworzone żadne nowe wątki).
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);nie zostanie wykonany.