Tôi chỉ có một câu hỏi mà tôi không thể trả lời.
Giả sử bạn có định nghĩa vòng lặp này trong Java:
while (i == i) ;
Loại ivà giá trị của inếu vòng lặp không phải là một vòng lặp vô hạn và chương trình chỉ sử dụng một luồng ?
Tôi chỉ có một câu hỏi mà tôi không thể trả lời.
Giả sử bạn có định nghĩa vòng lặp này trong Java:
while (i == i) ;
Loại ivà giá trị của inếu vòng lặp không phải là một vòng lặp vô hạn và chương trình chỉ sử dụng một luồng ?
Câu trả lời:
double i = Double.NaN;
API cho Double.equals () đánh vần câu trả lời: "Double.NaN == Double.NaN có giá trị sai". Điều này được xây dựng trong Đặc tả ngôn ngữ Java trong " Các kiểu dấu phẩy động, định dạng và giá trị ":
NaNlà không có thứ tự, do đó số toán tử so sánh<,<=,>, và>=trở lạifalsenếu một trong hai hoặc cả hai toán hạng làNaN. Toán tử đẳng thức==trả vềfalsenếu một toán hạng làNaNvà toán tử bất đẳng thức!=trả vềtruenếu một toán hạng làNaN. Cụ thể,x!=xlàtruenếu và chỉ khixlàNaN, và(x<y) == !(x>=y)sẽ làfalsenếuxhoặcylàNaN.
x == xphải luôn luôn đúng. Tại sao mọi thứ không nên bằng chính nó?
null=nulllà null. NULL IS NULLlà 1.
Giá trị của isau đó là không hợp lệ. "Không phải là một con số".
Sau một vài lần googling, tôi phát hiện ra rằng bạn CÓ THỂ có NaN (Không phải là Số) trong Java! Vì vậy, số Float Pointing là Kiểu dữ liệu và Giá trị là NaN. Xem tại đây
double i = Double.NaN;
NaN không bằng bất cứ thứ gì, kể cả chính nó.
float i = Float.NaN;
while(i == i) ;
System.out.println("Not infinite!");
Vì những người khác nói rằng đó là NaN, tôi đã tò mò về việc triển khai chính thức (JDK 6) Double.isNaNvà kìa:
/**
* 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);
}
Hãy nghĩ về Nan tương đương với ngoại lệ nhưng sử dụng giá trị ma thuật trong phép tính. Bởi vì một phép tính thất bại - ví dụ căn bậc hai của âm, chia cho số 0, v.v. - không có ý nghĩa gì khi so sánh chúng với bất kỳ thứ gì khác. Xét cho cùng, nếu chia cho 0 là một nan thì nó có tương đương với căn bậc hai của -2 hoặc căn bậc hai của -3 không?
Nan cho phép một phép tính bao gồm một bước trả về một câu trả lời không hợp lệ để hoàn thành mà không đưa ra các ngoại lệ bổ sung. Để xác minh câu trả lời là giá trị, chỉ cần kiểm tra mức độ không nghiêm trọng (đó là từ nếu không tôi đóng gói) thông qua Float.isNan () o tương đương.
Tôi sẽ thêm
float i = Float.NaN;
cũng như
double i = Double.NaN;
Một mẹo phổ biến trong các loại câu hỏi này trong giả định bạn đưa ra rằng tôi là một int. Các giả định phổ biến khác có thể là s là String, x, y là double, ch là char, b là byte, v.v ... Nếu bạn thấy một câu hỏi như thế này, bạn có thể đặt cược rằng 'i' không phải là loại mong đợi của nó.
Một câu hỏi tương tự là; Điều này không bao giờ lặp, 'x' là gì
while(x == x && x != x + 0) { }
Một câu hỏi khác tôi khá thích là; Vòng lặp này là một vòng lặp vô hạn, các giá trị có thể có của x là gì. (: Tôi đếm mười hai người trong số họ :)
while(x != 0 && x == -x) { }
Tôi biết đây là một câu hỏi Java, nhưng xem xét câu hỏi cho các ngôn ngữ khác là hấp dẫn.
Trong C, một loại đơn giản như 'int' có thể biểu hiện 'chấm dứt trước khi vũ trụ trở nên lạnh' nếu 'i' được tuyên bố là không ổn định (vì vậy trình biên dịch sẽ buộc phải thực hiện hai lần đọc 'i' cho mỗi lần lặp) và nếu 'tôi' thực sự nằm trong bộ nhớ nơi mà thứ khác có thể ảnh hưởng đến nó. Sau đó, vòng lặp sẽ chấm dứt khi 'i' thay đổi giữa hai lần đọc của một lần lặp. ( Đã thêm : một vị trí có thể - trong một máy vi tính nơi 'i' thực sự được đặt tại địa chỉ của cổng I / O, có lẽ được kết nối với cảm biến vị trí. Sẽ hợp lý hơn nếu 'i' là biến con trỏ ( một con trỏ tới bộ nhớ dễ bay hơi) và câu lệnh là ' while (*i == *i);'.)
Bằng chứng là các câu trả lời khác, trong C ++, toán tử '==' có thể được cung cấp bởi người dùng nếu tôi thuộc lớp do người dùng định nghĩa, vì vậy mọi thứ đều có thể.
Thay vì NaN, trong ngôn ngữ dựa trên SQL, vòng lặp sẽ không vô hạn nếu giá trị của i là NULL; tuy nhiên, bất kỳ giá trị không phải NULL nào cũng sẽ làm cho vòng lặp trở nên vô hạn. Điều này khá giống với Java, trong đó bất kỳ số nào (trái ngược với NaN) làm cho vòng lặp là vô hạn.
Tôi không thấy các cấu trúc có bất kỳ sử dụng thực tế, nhưng đó là một câu hỏi đố thú vị.
Tôi đã rất ngạc nhiên khi không thấy giải pháp này:
while (sin(x) == sin(x)) //probably won't eval to true
Để trả lời một bình luận, hãy thử chạy nó:
double x = 10.5f;
assert (x == asin(sin(x)));
x luôn luôn phải bằng arcsine (sin (x)) trong lý thuyết, nhưng trong thực tế thì không.
x, điều này sẽ mang lại kết quả chính xác tương tự với độ chính xác tương tự. Arcsin không thể đảo ngược kết quả của một tội lỗi với các số dấu phẩy động bởi vì giá trị được chuyển đến asin()sẽ không chính xác. Do đó, kết quả asin()sẽ không chính xác, làm x == asin(sin(x))sai. Ngoài ra, arcsin không nhất thiết phải "hoàn tác" một hoạt động tội lỗi. Hàm sin có thể cho cùng một kết quả cho nhiều giá trị của x, đó là lý do tại sao asin()chỉ trả về các số giữa -π / 2 và π / 2.
i == ikhông phải là nguyên tử. Chứng minh bởi chương trình như vậy:
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);
}
Cập nhật Dưới đây là một ví dụ nữa về vòng lặp không vô hạn (không có chủ đề mới nào được tạo).
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);không bao giờ thực hiện.