Bagaimana bisa “while (i == i);” menjadi loop non-tak terbatas dalam aplikasi berulir tunggal?


141

Saya hanya punya pertanyaan yang tidak bisa saya jawab.

Misalkan Anda memiliki definisi loop ini di Jawa:

while (i == i) ;

Apa jenis idan nilai ijika loop bukan infinite loop dan program hanya menggunakan satu utas ?


7
oh demi Tuhan, akankah orang mendapat kehormatan untuk berkomentar mengapa mereka kalah? ini ditandai sebagai teka-teki, apa masalahnya ???
user54579

10
Saya pikir beberapa orang tidak bisa berhenti downvoting untuk apa pun.
FerranB

1
Bah, maaf karena menyebabkan ini: / Aku benar-benar hanya ingin jawabannya, dan aku tidak bisa menyelesaikannya sendiri
Zizzencs

1
@nickolai, itulah sifat SO - drive-by downvoting sayangnya kenyataan dan ide yang membutuhkan komentar telah dibahas dan ditolak. Tapi sepertinya "komunitas" mendukung pertanyaan ini.
paxdiablo

1
Salah satu trik dari pertanyaan semacam ini adalah bahwa orang menganggap jenis nama variabel tertentu yaitu i adalah int, d adalah dobel, s adalah string atau pendek, ch adalah char, l adalah panjang, b untuk byte atau boolean. Anda harus bertanya pada diri sendiri jenis apa yang disarankan dan apa itu.
Peter Lawrey

Jawaban:


125
double i = Double.NaN;

API untuk Double.equals () merinci jawabannya: "Double.NaN == Double.NaN memiliki nilai false". Ini dijabarkan dalam Spesifikasi Bahasa Jawa di bawah " Tipe Titik-Apung, Format, dan Nilai ":

NaNadalah unordered, sehingga numerik operator perbandingan <, <=, >, dan >= kembali falsejika salah satu atau kedua operan NaN. Operator kesetaraan ==kembali falsejika salah satu operan NaN, dan operator ketidaksetaraan !=kembali truejika salah satu operan NaN. Secara khusus, x!=xadalah truejika dan hanya jika xyaituNaN , dan (x<y) == !(x>=y)akan falsejika xatau yadalah NaN.


1
OH jadi Anda BISA melakukan "Bukan Angka"!
Filip Ekberg

12
secara matematisnya kuat, mengapa satu angka yang tidak nyata sama dengan yang lainnya? 5/0! = Sqrt (-4)
Gordon Gustafson

2
@CrazyJugglerDrummer: Mungkin, tetapi juga x == xharus selalu benar. Mengapa sesuatu tidak sama dengan dirinya sendiri?
Bart van Heukelom

1
Bart: karena sungguh, tidak diketahui tidak selalu sama dengan tidak dikenal. Terkadang ini berguna, itu sebabnya database memiliki NULL ...
Konerak

2
@inovaovao: tidak, dalam DB, null=nulladalah nol. NULL IS NULLadalah 1.
Konerak

29

Nilai iini kemudian tidak valid. "Bukan Angka".

Setelah beberapa googling, saya menemukan bahwa Anda BISA memiliki NaN (Bukan Angka) di Jawa! Jadi, angka Float Pointing adalah Tipe Data dan Nilainya adalah NaN. Lihat di sini


12
Yap, itu dia. Nilai i adalah Jon Skeet.
Andrew Rollings

Saya biasanya membenci orang yang downvote tanpa alasan ... Saya adalah orang pertama yang mengatakan "Bukan Angka" tetapi tidak berpikir java bisa mengatasinya, karena tidak menangani hal lain yang keren.
Filip Ekberg



8

Saya tidak yakin, tapi saya percaya (i == i) bukan operasi atom dalam proses multithreaded, jadi jika nilai saya akan diubah oleh utas lainnya antara dorongan nilainya untuk ditumpuk pada utas yang menjalankan loop, maka kondisi itu dapat salah.


8

Karena yang lain bilang itu NaN, saya jadi penasaran dengan implementasi (JDK 6) resmi Double.isNaN, dan lihat:

/**
 * 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);
}

2

Pikirkan Nan sebagai ekuivalen pengecualian tetapi menggunakan nilai ajaib dalam perhitungan. Karena perhitungan gagal - misalnya akar kuadrat dari negatif, bagi dengan nol dll - tidak masuk akal membandingkannya dengan yang lain. Lagi pula jika bagi dengan nol adalah nan apakah itu setara dengan akar kuadrat -2 atau kuadrat -3?

Nan memungkinkan perhitungan yang mencakup langkah yang mengembalikan jawaban yang tidak valid untuk diselesaikan tanpa memasukkan pengecualian tambahan. Untuk memverifikasi jawabannya adalah nilai, cukup tes untuk ketidakberesan (apakah itu kata jika tidak saya kemas) melalui Float.isNan () atau yang setara.


3
Akan lebih mudah untuk menganggapnya sebagai exceptioniolbut jika saya benar-benar tahu apa itu exceptioniolbut :-).
paxdiablo

2

Saya akan menambahkan

float i = Float.NaN;

sebaik

double i = Double.NaN;

Trik umum dalam pertanyaan-pertanyaan semacam ini adalah dengan asumsi Anda membuat saya adalah seorang int. Asumsi umum lainnya yang mungkin adalah s adalah String, x, y adalah dobel, ch adalah char, b adalah byte dll. Jika Anda melihat pertanyaan seperti ini, Anda dapat bertaruh bahwa 'i' bukan tipe harapannya.

Pertanyaan serupa adalah; Ini tidak pernah berulang, apa itu 'x'

while(x == x && x != x + 0) { }

Pertanyaan lain yang saya sukai adalah; Loop ini adalah loop tak terbatas, berapakah nilai yang mungkin dari x. (: Saya hitung dua belas dari mereka :)

while(x != 0 && x == -x) { }

0

Saya tahu ini adalah pertanyaan Java, tetapi mempertimbangkan pertanyaan untuk bahasa lain sangat menarik.

Dalam C, tipe sederhana seperti 'int' dapat menunjukkan 'berakhir sebelum alam semesta menjadi dingin' perilaku jika 'i' dinyatakan sebagai volatile (sehingga kompiler akan dipaksa untuk melakukan dua pembacaan 'i' untuk setiap iterasi) dan jika 'i' benar-benar ada di memori di mana sesuatu yang lain dapat memengaruhinya. Maka loop akan berakhir ketika 'i' berubah antara dua bacaan dari satu iterasi. ( Ditambahkan : tempat yang memungkinkan - di komputer mikro di mana 'i' sebenarnya terletak di alamat port I / O, mungkin terhubung ke sensor posisi. Akan lebih masuk akal jika 'i' adalah variabel penunjuk ( pointer ke memori volatile) dan pernyataannya adalah ' while (*i == *i);'.)

Sebagaimana dibuktikan oleh jawaban lain, dalam C ++, operator '==' dapat diberikan oleh pengguna jika saya adalah kelas yang ditentukan pengguna, jadi apa pun mungkin terjadi.

Alih-alih seperti NaN, dalam bahasa berbasis SQL, loop tidak akan terbatas jika nilai saya adalah NULL; Namun, nilai non-NULL apa pun akan membuat loop tak terbatas. Ini agak seperti Java, di mana angka apa pun (sebagai lawan dari NaN) membuat loop tak terbatas.

Saya tidak melihat konstruksinya memiliki penggunaan praktis, tetapi ini adalah pertanyaan trivia yang menarik.


0

Saya terkejut tidak melihat solusi ini:

while (sin(x) == sin(x)) //probably won't eval to true

Menanggapi komentar, coba jalankan ini:

double x = 10.5f;
assert (x == asin(sin(x)));

x harus selalu sama dengan arcsine (sin (x)) dalam teori, tetapi dalam praktiknya tidak.


3
Kenapa tidak? Anda melakukan perhitungan yang persis sama pada data yang persis sama, kedua hasil akan mengandung kesalahan yang sama persis.
Loren Pechtel

Saya tidak ingat persis di mana saya membacanya, tetapi tergantung pada mesin / implementasi Anda, dosa (x) pada satu panggilan fungsi memiliki peluang sangat kecil untuk menyamakan dosa (x) dari panggilan yang berbeda. Ini berkaitan dengan keakuratan angka floating point (ada sesuatu yang khusus tentang fungsi trigonometri yang membuat mereka tidak mengembalikan nilai yang sama dua kali).
jkeys

Lihat pembaruan saya. Arcsine "membatalkan" dosa x, jadi mereka harus sama, tetapi mereka tidak sama.
jkeys

Itu bukan hal yang sama. Seperti yang dikatakan Loren, Anda menjalankan operasi yang sama persis x, yang akan menghasilkan hasil yang sama persis dengan ketidaktepatan yang sama persis. Arcsin tidak dapat membalikkan hasil dosa dengan angka floating point karena nilai yang diteruskan asin()tidak akan akurat. Karena itu, hasilnya asin()akan tidak akurat, membuat x == asin(sin(x))salah. Juga, arcsin tidak harus "membatalkan" operasi dosa - fungsi dosa dapat memberikan hasil yang sama untuk beberapa nilai x, yang mengapa asin()hanya mengembalikan angka antara -π / 2 dan π / 2.
hbw

2
Dengan kata lain, arcsin tidak selalu dapat "membatalkan" fungsi dosa karena tidak mungkin bagi arcsin untuk mengetahui apa sudut aslinya. Sebagai contoh, dosa dari keduanya π / 2 dan 5 give / 2 memberi 1. Tapi apa yang arcsin (1)? Jelas tidak bisa mengembalikan keduanya, kan? Oleh karena itu, hasil dari arcsin harus dibatasi pada kisaran 2π radian, yang berarti bahwa ia tidak dapat benar-benar membatalkan hasil fungsi dosa kecuali jika sudut aslinya adalah antara 0 dan 2π, atau dalam kasus C, -π / 2 dan π / 2. (Memang, arcsin (sin (5π / 2)) = π / 2.) Bagaimanapun, itu adalah penjelasan yang sangat panjang, tapi saya harap itu membantu menjernihkan kesalahpahaman.
hbw

0

Bukan loop tak terbatas, satu utas :)

import static B.*;
public class A {
    public static void main(String[] args) {
        System.out.println("Still Running");
        while (i == i) ;
    }
}


public class B {

    public static int i;
    static {
        System.exit(0);
    }
}

-1

i == ibukan atom. Terbukti oleh program tersebut:

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);
}

Perbarui Berikut ini adalah satu lagi contoh loop tidak-tak terbatas (tidak ada utas baru yang dibuat).

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);
    }
}

@ Charles Goodwin Apa yang Anda katakan dengan fakta bahwa tidak ada kemungkinan untuk menulis program Java menggunakan satu utas :), jadi semua solusi lain menggunakan setidaknya dua utas (persis sama dengan program kedua saya di bagian 'Perbarui' lakukan).
Andrey

Itu tidak mengerem loop. Kode apa pun setelah while (i == i);tidak akan pernah dijalankan.
aalku

Finalisasi menggunakan utas lain, tapi itu hal yang baik untuk ditunjukkan. Itulah alasan pertanyaan awal mengatakan "dan program hanya menggunakan satu utas" .. jenis yang secara eksplisit menyatakan bahwa ini adalah jawaban yang jelas dan mereka ingin Anda melihat lebih jauh.
Bill K
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.