2012-02-18 14 views
25

Tại sao so sánh này cho tôi 'sai'? Tôi nhìn nguồn và Float.NaN được định nghĩa làFloat.NaN == Float.NaN

/** 
* A constant holding a Not-a-Number (NaN) value of type 
* <code>float</code>. It is equivalent to the value returned by 
* <code>Float.intBitsToFloat(0x7fc00000)</code>. 
*/ 
public static final float NaN = 0.0f/0.0f; 

EDIT: đáng ngạc nhiên, nếu tôi làm điều này:

System.out.println("FC " + (Float.compare(Float.NaN, Float.NaN))); 

nó mang lại cho tôi 0. Vì vậy, Float.compare() không nghĩ rằng NaN bằng chính nó!

Trả lời

32

Bởi vì Java thực hiện các tiêu chuẩn dấu chấm động IEEE-754 mà đảm bảo rằng bất cứ so sánh với NaN sẽ trả về false (trừ != mà trả về true)

Điều đó có nghĩa, bạn không thể kiểm tra theo những cách thông thường của bạn cho dù một nổi số điểm là NaN, vì vậy bạn có thể diễn giải lại cả hai con số như ints và so sánh chúng hoặc sử dụng các giải pháp thông minh hơn nhiều:

def isNan(val): 
    return val != val 
+5

Ngoại trừ '! =' So sánh, trả về 'true'. –

+3

Bạn thực sự có thể kiểm tra NaN theo cách này! nếu 'x == x' là sai thì x là NaN. –

+0

@Daniel Ups đúng bạn cảm ơn! Đơn giản hóa quá nhiều. – Voo

53

sử dụng Float.isNaN để kiểm tra giá trị NaN.

+6

+1 Giải pháp tốt hơn, nhưng giải thích kém! –

+1

@Rolf ツ Không có gì để thêm, nó khá đơn giản. – Flawyte

-1

Tất cả những gì tôi cần nói là: Wikipedia About NaN.

Nó được viết khá rõ ràng. Phần thú vị là điểm nổi NaN của tiêu chuẩn thông thường thể hiện một NaN theo cách này:

s111 1111 1xxx xxxx xxxx xxxx xxxx xxxx

các s là dấu hiệu (âm hoặc dương), số 1 ​​là số mũ và x được coi là trọng tải.

Nhìn vào tải trọng NaN không bằng NaN và có rất ít khả năng những thông tin tải trọng này thú vị đối với bạn với tư cách là nhà phát triển (ví dụ: số phức).

Một điều nữa là trong tiêu chuẩn chúng có tín hiệu và khá NaN. Một NaN báo hiệu (sNaN) có nghĩa là một NaN sẽ làm tăng phản ứng như một ngoại lệ. Nó nên được sử dụng để nói to rằng bạn có một vấn đề trong phương trình của bạn. Một NaN yên tĩnh (qNaN) là một NaN được âm thầm truyền vào.

Một sNaN đã tạo tín hiệu được chuyển thành qNaN để không tiếp tục tạo thêm bất kỳ tín hiệu nào trong các hoạt động tiếp theo. Hãy nhớ rằng một số hệ thống định nghĩa i^0 = 1 là một hằng số mà NaN^0 = 1 giữ đúng. Vì vậy, có những trường hợp mà mọi người tính toán với NaN.

Vì vậy, cuối cùng tôi sẽ đi với điều này: qNaN! = SNaN nhưng điều này là nội bộ và không thể quan sát được cho người dùng (bạn không thể kiểm tra điều đó). Kết hợp thanh toán và ký tên (có bạn có thể có NaN âm và dương) và dường như tôi luôn trả về NaN! = NaN trông giống như một sự lựa chọn khôn ngoan hơn mà cuối cùng tôi đã học được -> Tôi sẽ không bao giờ phàn nàn hay băn khoăn về sự bất bình đẳng của NaN một lần nữa. Khen ngợi những người đã chu đáo cho chúng tôi một tiêu chuẩn tốt như vậy!

Nhân tiện: Java sử dụng NaN dương với trọng tải là 0 (tất cả x là số không).

+0

Số phức tạp phải làm gì với tải trọng? –