ฉันเพิ่งมีคำถามที่ฉันไม่สามารถตอบได้
สมมติว่าคุณมีนิยามลูปนี้ใน Java:
while (i == i) ;
ชนิดของiและค่าของiถ้าลูปไม่ใช่ลูปไม่สิ้นสุดและโปรแกรมใช้เธรดเดียวเท่านั้น ?
ฉันเพิ่งมีคำถามที่ฉันไม่สามารถตอบได้
สมมติว่าคุณมีนิยามลูปนี้ใน Java:
while (i == i) ;
ชนิดของiและค่าของiถ้าลูปไม่ใช่ลูปไม่สิ้นสุดและโปรแกรมใช้เธรดเดียวเท่านั้น ?
คำตอบ:
double i = Double.NaN;
API สำหรับDouble.equals ()สะกดคำตอบ: "Double.NaN == Double.NaN มีค่า false" มีการอธิบายอย่างละเอียดในข้อกำหนดภาษา Java ภายใต้ " ประเภทจุดลอยตัวรูปแบบและค่า ":
NaNคือเรียงลำดับดังนั้นการดำเนินการเปรียบเทียบตัวเลข<,<=,>และ>=ผลตอบแทนถ้าอย่างใดอย่างหนึ่งหรือทั้งสองตัวถูกดำเนินการอยู่falseNaNผู้ประกอบการไม่เท่าเทียมกันที่==ผลตอบแทนfalseถ้าทั้งตัวถูกดำเนินการเป็นNaNและผู้ประกอบการอสมการ!=ผลตอบแทนถ้าทั้งตัวถูกดำเนินการคือtrueโดยเฉพาะอย่างยิ่งคือถ้าหากมีและจะเป็นถ้าหรือเป็นNaNx!=xtruexNaN(x<y) == !(x>=y)falsexyNaN
x == xควรเป็นจริงเสมอ ทำไมไม่มีอะไรที่ไม่เท่าเทียมกัน?
null=nullเป็นโมฆะ NULL IS NULLคือ 1.
ค่าของiนั้นไม่ถูกต้อง "ไม่ใช่ตัวเลข"
หลังจาก googling ฉันพบว่าคุณสามารถมี NaN (ไม่ใช่ตัวเลข) ใน Java! ดังนั้นจำนวนจุดลอยตัวคือชนิดข้อมูลและค่าคือ NaN ดูที่นี่
double i = Double.NaN;
NaN ไม่เท่ากับสิ่งใดรวมถึงตัวมันเอง
float i = Float.NaN;
while(i == i) ;
System.out.println("Not infinite!");
ฉันไม่แน่ใจ แต่ฉันเชื่อว่า (i == i) ไม่ใช่การดำเนินการปรมาณูในกระบวนการมัลติเธรดดังนั้นหากค่า i จะถูกเปลี่ยนโดยเธรดอื่น ๆ ระหว่างการกดของค่ามันเพื่อสแต็กในเธรดที่ดำเนินการลูปแล้วเงื่อนไขนั้นสามารถ เป็นเท็จ
เนื่องจากคนอื่น ๆ บอกว่าเป็น NaN ฉันอยากรู้เกี่ยวกับการใช้งานอย่างเป็นทางการ (JDK 6) Double.isNaNและเห็นว่า:
/**
* 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 หรือรากที่สองของ -3?
น่านช่วยให้การคำนวณที่มีขั้นตอนที่ส่งกลับคำตอบที่ไม่ถูกต้องให้เสร็จสมบูรณ์โดยไม่ต้องมีข้อยกเว้นพิเศษ ในการตรวจสอบว่าคำตอบคือค่าเพียงแค่ทดสอบว่าไม่ใช่ความจริง (คือคำว่าไม่ใช่ถ้าฉันใส่ไว้) ผ่านทาง Float.isNan () o ที่เทียบเท่ากัน
ฉันจะเพิ่ม
float i = Float.NaN;
เช่นกัน
double i = Double.NaN;
เคล็ดลับทั่วไปในคำถามประเภทนี้ในสมมุติฐานที่คุณทำให้ฉันเป็นคนโง่ ข้อสันนิษฐานทั่วไปอื่น ๆ อาจเป็น s คือ String, x, y เป็นสองเท่า, ch คือ char, b เป็นไบต์เป็นต้นหากคุณเห็นคำถามเช่นนี้คุณสามารถเดิมพันได้ว่า 'i' ไม่ใช่ประเภทที่คาดหวัง
คำถามที่คล้ายกันคือ; สิ่งนี้ไม่เคยลูป 'x' คืออะไร
while(x == x && x != x + 0) { }
อีกคำถามที่ฉันชอบคือ; ลูปนี้เป็นลูปไม่สิ้นสุดสิ่งที่เป็นไปได้ของค่า x (: ฉันนับพวกเขาสิบสองคน :)
while(x != 0 && x == -x) { }
ฉันรู้ว่านี่เป็นคำถามเกี่ยวกับ Java แต่การพิจารณาคำถามสำหรับภาษาอื่นนั้นน่าสนใจ
ใน C ประเภทง่ายๆเช่น 'int' สามารถแสดง 'ยุติก่อนที่เอกภพจะเย็นลง' ถ้า 'i' ถูกประกาศว่าเป็นสารระเหย (ดังนั้นคอมไพเลอร์จะถูกบังคับให้อ่าน 'i' สองครั้งต่อการทำซ้ำ) และถ้า 'i' อยู่ในความทรงจำจริงๆ จากนั้นลูปจะยุติลงเมื่อ 'i' เปลี่ยนไประหว่างการอ่านซ้ำสองครั้งของการวนซ้ำสองครั้ง ( เพิ่ม : สถานที่ที่เป็นไปได้ - ในไมโครคอมพิวเตอร์ที่ 'i' ตั้งอยู่จริงตามที่อยู่ของพอร์ต I / O อาจเชื่อมต่อกับเซ็นเซอร์ตำแหน่งอาจเป็นไปได้มากขึ้นถ้า 'i' เป็นตัวแปรตัวชี้ ( ตัวชี้ไปยังหน่วยความจำระเหย) และคำสั่งคือ ' while (*i == *i);')
ดังที่เห็นได้จากคำตอบอื่น ๆ ใน C ++ ผู้ใช้สามารถระบุโอเปอเรเตอร์ '==' ได้หากฉันเป็นคลาสที่ผู้ใช้กำหนดดังนั้นอาจมีอะไรก็ได้ที่เป็นไปได้
ค่อนข้างเหมือน NaN ในภาษาที่ใช้ SQL ลูปจะไม่สิ้นสุดหากค่าของ i เป็น NULL; อย่างไรก็ตามค่าที่ไม่ใช่ค่า NULL จะทำให้วนซ้ำไม่สิ้นสุด นี่เป็นเหมือน Java ซึ่งจำนวนใด ๆ (ตรงข้ามกับ NaN) ทำให้วนรอบไม่สิ้นสุด
ฉันไม่เห็นสิ่งก่อสร้างที่ใช้งานได้จริง แต่เป็นคำถามที่น่าสนใจ
ฉันประหลาดใจที่ไม่เห็นโซลูชันนี้:
while (sin(x) == sin(x)) //probably won't eval to true
ในการตอบกลับความคิดเห็นลองใช้สิ่งนี้:
double x = 10.5f;
assert (x == asin(sin(x)));
x ควรเท่ากับ arcsine (sin (x)) ในทางทฤษฎีเสมอ แต่ในทางปฏิบัติมันไม่ได้
xที่ซึ่งควรให้ผลลัพธ์ที่เหมือนกันแน่นอนโดยมีความไม่ถูกต้องเหมือนกัน Arcsin ไม่สามารถย้อนกลับผลลัพธ์ของความบาปด้วยจำนวนจุดลอยตัวเนื่องจากค่าที่ส่งผ่านไปasin()นั้นจะไม่แม่นยำอย่างแน่นอน ดังนั้นผลลัพธ์ของการasin()จะไม่ถูกต้องทำให้x == asin(sin(x))เป็นเท็จ นอกจากนี้ arcsin ไม่จำเป็นต้อง "เลิกทำ" การดำเนินการบาป - ฟังก์ชัน sin สามารถให้ผลลัพธ์เดียวกันสำหรับค่าหลายค่าของ x ซึ่งเป็นเหตุผลว่าทำไมasin()ส่งกลับตัวเลขระหว่าง-π / 2 ถึงπ / 2 เท่านั้น
ไม่ใช่วงวนไม่สิ้นสุดหนึ่งกระทู้ :)
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);
}
}
i == iไม่ใช่อะตอม พิสูจน์แล้วโดยโปรแกรมดังกล่าว:
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);
}
อัปเดตที่ นี่เป็นอีกตัวอย่างหนึ่งของการวนซ้ำแบบไม่สิ้นสุด (ไม่มีการสร้างเธรดใหม่)
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);เคยชินรัน