2009-07-17 22 views
77

Ai đó có thể giải thích điều này cho tôi không? Trong C# double.NaN không bằng gấp đôi.NaNTại sao gấp đôi.NaN không bằng chính nó?

bool huh = double.NaN == double.NaN; // huh = false 
bool huh2 = double.NaN >= 0; // huh2 = false 
bool huh3 = double.NaN <= 0; // huh3 = false 

Tôi có thể so sánh hằng số với số double.NaN và nhận được sự thật?

+11

Chỉ cần giải thích những điều bạn đang mắc phải: NaN không bằng gì, thậm chí không phải chính nó. Điều này là theo định nghĩa. http://en.wikipedia.org/wiki/NaN – Falaina

+2

Điều tôi nghĩ là không may là bối cảnh bị mất. Nếu chúng tôi có hai đôi, và cả hai được gán một giá trị của NaN để đại diện cho giá trị thực tế 1/0. Chúng phải bằng nhau, nhưng vì bối cảnh bị mất, chúng được coi là không bằng nhau –

+0

Bạn nói đúng, một dòng mã bổ sung cần phải được triển khai cho trường hợp cụ thể đó. – Carlo

Trả lời

127

Nếu bạn tò mò, đây là những gì Double.IsNaN trông giống như:

public static bool IsNaN(double d) 
{ 
    return (d != d); 
} 

Funky, huh?

+4

Rất sôi nổi! Cũng rất thông minh khi bạn nghĩ về nó. –

+0

Thú vị. Tôi không biết điều đó. Làm cho tinh thần, một khi bạn nhìn thấy nó mặc dù, do định nghĩa của NaN ... – Noldorin

+10

Đó là lạ hoàn toàn. Nhưng sau đó một lần nữa, như vậy là tuyên bố của NaN: 'công khai const đôi NaN = (đôi) 1.0/(đôi) 0,0;' –

15
bool isNaN = Double.IsNaN(yourNumber) 
6

Có một chức năng chuyên biệt cho việc này:

double.IsNan(huh); 
5

Sử dụng phương pháp "Double.IsNaN (giá trị)" để kiểm tra các điều kiện này.

7

Sử dụng Double.IsNan() để kiểm tra tính bình đẳng tại đây. Lý do là NaN không phải là một con số.

9

Hành vi có chủ đích. Lý do NaN đại diện cho một cái gì đó mà không phải là một số và do đó, đó là một loại bắt tất cả cho nhiều thứ.

Cách thích hợp để so sánh thứ gì đó là NaN là sử dụng hàm IsNaN.

3

Trên thực tế, bạn đã tìm thấy cách để kiểm tra xem một IEEE-754 số dấu chấm động là NaN: nó chỉ là giá trị dấu chấm động (hoặc dãy các giá trị, bởi vì có một số Nans) mà đánh giá để False nếu so với chính nó, ví dụ:

bool isNaN(double v) { 
    return v != v; 
} 

Dưới mui xe, phương pháp Double.IsNaN có thể thực sự làm điều tương tự. Bạn vẫn nên sử dụng nó, bởi vì hành vi này khá bất ngờ đối với bất kỳ ai không biết về tiêu chuẩn FP.

2

Điều duy nhất chúng tôi biết về NaN là "Không phải là số". Điều đó không có nghĩa là nó có một giá trị được hỗ trợ với trạng thái của nó. Ví dụ:

∞ + (- ∞) = NaN

0/0 = NaN

(∞ + (- ∞)) <> (0/0)

Dưới đây là một số C# để chứng minh

var infinity = 100d/0; 
var negInfinity = -100d/0; 

var notANumber = infinity + negInfinity; 
Console.WriteLine("Negative Infinity plus Infinity is NaN: {0}", double.IsNaN(notANumber)); 

var notANumber2 = 0d/0d; 
Console.WriteLine("Zero divided by Zero is NaN: {0}", double.IsNaN(notANumber2)); 

Console.WriteLine("These two are not equal: {0}", notANumber == notANumber2); 
+0

100/0 không phải là NaN, nó là vô cùng! http://docs.sun.com/source/806-3568/ncg_goldberg.html#918 –

+0

Bạn nói đúng. Tôi đang sửa đổi. –

2

Lý do của Double.NaN != Double.NaN là đơn giản:

Bạn có mong đợi 0/0 giống với Math.Sqrt(-3) không? Và giống như Math.Sqrt(-7)?

Có lỗi trong C# theo ý kiến ​​của tôi, trong đó Equals() không được ghi đè cho NaN.

Assert.IsTrue(Double.NaN != Double.NaN); 
Assert.IsTrue(Double.NaN.Equals(Double.NaN)); 

Đồng thời

Assert.IsTrue(Double.PositiveInfinity == Double.NegativeInfinity); 
Assert.IsTrue(Double.PositiveInfinity.Equals(Double.PositiveInfinity)); 
// same for Double.NegativeInfinity and Single 

Sử dụng chức năng tĩnh cho DoubleSingle, ví dụ

Double.IsNaN(value) && Double.IsInfinity(value); 

Hoặc cụ thể hơn:

Double.IsPositiveInfinity(value); 
Double.IsNegativeInfinity(value); 
2

Nhà điều hành bình đẳng xem xét hai giá trị NaN là bất bình đẳng với nhau. Nói chung, các toán tử Double không thể được sử dụng để so sánh Double.NaN với các giá trị Double khác, mặc dù các phương thức so sánh (chẳng hạn như BằngCompareTo) có thể. xem dưới đây ví dụ

tham chiếu từ msdn

class Program 
{ 
    static void Main(string[] args) 
    { 
     Double i = Double.NaN; 
     while (!i.Equals(i)) //this would be result in false 
     //while(i != i) // this would result in true. 
     { 
      Console.WriteLine("Hello"); 
     } 
    } 
} 

here là .net fiddle cho cùng.

Các vấn đề liên quan