2013-02-27 54 views
7

Lợi ích của NaN, PositiveInfinity hoặc NegativeInfinity cho floatdouble là gì? Khi nào chúng ta nên sử dụng hoặc tránh chúng?Khi nào sử dụng NaN hoặc +/- Infinity?

Nếu có hằng số như vậy, tại sao float.Parse("a") ném lỗi thay vì trả về float.NaN?

Làm thế nào là NaN khác với null? Tại sao là division by zero thậm chí có thể cho các loại thả nổi?

+0

bạn có thể sử dụng TryParse hơn là phân tích cú pháp? – Liam

+2

Được sử dụng vì hoạt động toán học. – Evgeny

+8

@Evgeny: bình luận mơ hồ nhất. –

Trả lời

7

Họ không phải là rất nhiều thứ mà bạn sử dụng vì họ là một cái gì đó bạn cần phải nhận thức được:

double hmm = 1.0/0.0; 
double hmm2 = -1.0/0.0; 
double hmm3 = 0.0/0.0; 
Console.WriteLine("1/0 == {0}", hmm); 
Console.WriteLine("-1/0 == {0}", hmm2); 
Console.WriteLine("0/0 == {0}", hmm3); 

Output:

1/0 == Infinity 
-1/0 == -Infinity 
0/0 == NaN 

EDIT: Đối với câu hỏi này:

Nếu có các hằng số như thế này, tại sao float.Par se ("a") ném một lỗi thay vì trả về float.NaN?

double.NaN thực sự là một định nghĩa toán học một cách - đó là "định nghĩa" như 0.0/0.0 - trong khi dòng chữ "không phải là một con số" ngụ ý rằng một cái gì đó giống như double.Parse("a") cũng nên trở double.NaN, nó không. Tại sao?

linh cảm của tôi là bởi vì nó sẽ không thể để xác định xem double.NaN bạn nhận được là kết quả của dữ liệu rác (trong trường hợp của chuỗi) hoặc thực tế nghĩa của một số không xác định, giống như zero chia cho zero. Vì vậy, để tạo sự khác biệt giữa hai trường hợp này, double.Parse("a") ném một số Exception, điều mà tôi cảm thấy là chính xác hơn.

+0

Tại sao chia cho 0 có thể cho các loại nổi? – LZW

+1

@LZW Câu trả lời đơn giản: vì bạn có thể nhập/biên dịch/chạy '1.0/0.0' - trong các ngày cũ, điều này sẽ gây ra' DivideByZeroException', nhưng có các ứng dụng lý thuyết cho các giá trị 'Infinity' và' NaN' được xác định ví dụ, WPF sử dụng cả hai thứ này để biểu thị kích thước "unset" hoặc "undefined", v.v. – JerKimball

+0

@LZW: Trong nhiều trường hợp, xác định * cho dù * biểu thức dấu phẩy động có thể được đánh giá mà không có bất kỳ phép tính trung gian nào nằm ngoài phạm vi yêu cầu tính toán đắt hơn những tính toán cần thiết để đánh giá biểu thức khi mọi thứ nằm trong phạm vi. Cho phép mã để cố gắng đánh giá biểu thức và sau đó tìm hiểu xem có vấn đề nào rẻ hơn so với yêu cầu mã để phát hiện trước điều kiện có vấn đề hay không. – supercat

6

Nếu có hằng số như vậy tại sao float.Parse("a") lỗi ném thay vì trả lại float.NaN?

Bởi vì không ai trong số các lựa chọn thay thế bạn liệt kê được áp dụng ở đây:

PositiveInfinityNegativeInfinity chỉ đó - ví dụ: họ là kết quả của biểu thức như 1/0 hoặc -1/0.

NaN là kết quả của 0/0 - tức là biểu thức có kết quả không phải là (thường) được xác định rõ và không dẫn đến số.

float.Parse("a") không có gì giống như vậy. Phải thừa nhận rằng, nó có khả năng có thể được đại diện bởi NaN nhưng sau đó bạn không thể phân biệt giữa người dùng nhập giá trị float không hợp lệ (a) và giá trị float hợp lệ (NaN). Tuy nhiên, đây không phải là một đối số mạnh mẽ: NaNmột cách rõ ràng trình giữ chỗ cho một số không hợp lệ để nó có thể được sử dụng để đại diện cho đầu vào của người dùng không hợp lệ.

Mặt khác, có các loại khác có phương thức Parse và không có giá trị NaN (chẳng hạn như int). Đối với các loại này, Parsephải do đó báo hiệu lỗi. Nó sẽ không phù hợp (và do đó thiết kế API kém) để làm cho các phương thức khác nhau của phương thức Parse hoạt động khác nhau.

+2

parseFloat của JavaScript ("a") trả về NaN. – LZW

1

Ngoài các kết quả từ số học, các giá trị vô hạn có thể được sử dụng để xác định không có giới hạn cho ngữ cảnh.

Ví dụ: Kiểm soát WPF gốc yêu cầu một trong số các con của nó đo lường chính nó, trong bối cảnh không có giới hạn kích thước; ví dụ: availableSize là PositiveInfinity

Ref: MeasureOverride

+0

Đây là câu trả lời duy nhất cho ví dụ thế giới thực (không phải lý thuyết). – LZW

9

infinities được sử dụng vì chúng là một phần của hệ thống số học được hỗ trợ bởi dấu chấm động. Có nhiều hoạt động khác nhau, chẳng hạn như chia cho số không, trong đó vô cùng là một kết quả hữu ích và có tính toán học hợp lý. Rõ ràng, không có số lượng vật lý trực tiếp có thể là vô hạn (bạn không thể có vô số gam), nhưng vô cùng có thể là một giá trị hữu ích cho một số khía cạnh của một mô hình toán học của các quá trình vật lý hoặc những thứ khác mà con người mô hình hóa với máy tính.

NaN được sử dụng vì hệ thống số học chưa hoàn thành. Nghĩa là, có các phép toán với các giá trị đầu vào mà kết quả toán học thích hợp không thể biểu diễn trong dấu phẩy động. Ví dụ, sqrt (-1) là một hoạt động toán học hợp pháp, nhưng kết quả, số ảo i, không thể biểu diễn trong dấu phẩy động. Vì vậy, NaN được sử dụng như một trình giữ chỗ để chỉ ra rằng các giá trị đã đi ra ngoài các số dấu phẩy động. NaN cũng có thể được sử dụng cho các mục đích khác, chẳng hạn như đánh dấu dữ liệu không được khởi tạo khác để giúp gỡ lỗi.

float.Parse("a") ném lỗi thay vì trả về NaN vì đó không phải là hoạt động hợp pháp. Biểu thức này không thực hiện phép toán có kết quả phù hợp bên ngoài các số biểu diễn. Nó là một lỗi thực tế, do đó, nó ném một lỗi.

+0

Tôi thích câu trả lời này; nó giải thích tại sao Parse thất bại, như bạn về cơ bản đang cố gắng thống nhất hai loại không có mối quan hệ (float và string) – JerKimball

0

Để giải quyết NAN và vô cực, sử dụng này:

if (Double.IsNaN(YourValue) || Double.IsInfinity(YourValue)) 
{ 
    YourValue = 0; 
} 
Các vấn đề liên quan