2012-07-02 34 views
8

1.#INF là gì và tại sao truyền tới số float hoặc double ngăn chặn phân chia bằng 0 lỗi?
Ngoài ra, bất kỳ ý tưởng tuyệt vời nào về cách ngăn chặn chia cho 0? (Giống như bất kỳ macro hoặc mẫu) nào?Chia cho số 0 bằng không

int nQuota = 0; 

int nZero = 3/nQuota; //crash 
cout << nZero << endl; 

float fZero = 2/nQuota; //crash 
cout << fZero << endl; 

nếu tôi sử dụng thay vì:

int nZero = 3/(float)nQuota; 
cout << nZero << endl; 
//Output = -2147483648 

float fZero = 2/(float)nQuota; 
cout << fZero << endl; 
//Output = 1.#INF 
+2

thật thú vị. Mong một câu trả lời. –

+0

điều này có thể thú vị cho bạn: http://blog.regehr.org/archives/721 – cppanda

Trả lời

12

1.#INF là dương vô cực. Bạn sẽ nhận được nó khi bạn chia phao dương bằng 0 (nếu bạn chia số không 0 bằng 0 thì kết quả sẽ là "không phải là số").

Mặt khác, nếu bạn chia một số nguyên bằng 0, chương trình sẽ bị lỗi.

Lý do float fZero = 2/nQuota; sự cố là do cả hai toán hạng của toán tử / là số nguyên, do đó phép chia được thực hiện trên số nguyên. Nó không quan trọng là bạn sau đó lưu trữ kết quả trong một phao; C++ không có khái niệm gõ đích.

Tại sao tích cực vô cùng đúc thành một số nguyên là số nguyên nhỏ nhất, tôi không có ý tưởng.

+0

những gì về-2147483648? –

+1

-2147483648 là 1. # INF truyền tới một số nguyên. –

+3

Thông số C không xuất hiện để xác định kết quả chuyển đổi 'NaN' hoặc giá trị float vô hạn thành số nguyên. "Nếu giá trị is oating là fi nite hoặc NaN hoặc nếu phần không thể tách rời của giá trị exceeds oating vượt quá phạm vi của loại số nguyên, thì ngoại lệ" không hợp lệ "sẽ được nâng lên và giá trị kết quả không được xác định." – mkb

1

Bạn thường kiểm tra để đảm bảo rằng bạn không chia cho 0. Đoạn code dưới đây không phải là đặc biệt hữu ích nếu nQuota có giá trị hợp pháp nhưng nó không ngăn chặn tai nạn

int nQuota = 0; 
int nZero = 0; 
float fZero = 0; 
if (nQuota) 
    nZero = 3/nQuota; 
cout << nZero << endl; 

if (nQuota) 
    fZero = 2/nQuota; 
cout << fZero << endl; 
+0

Kinda đơn giản, nhưng nó giống như một sự quyến rũ. –

3

Wwhy sử dụng (float) hoặc (double) ngăn chặn sự phân chia bằng 0 của đâm?

Nó không nhất thiết. Tiêu chuẩn là phụ tùng tuyệt vời khi nói đến điểm nổi. Hầu hết các hệ thống sử dụng tiêu chuẩn điểm nổi IEEE ngày nay, và nói rằng hành động mặc định cho phép chia bằng 0 là trả về ± vô cùng chứ không phải là sự cố. Bạn có thể làm cho nó sụp đổ bằng cách cho phép các ngoại lệ dấu chấm động thích hợp.

Lưu ý tốt: Điều duy nhất mô hình ngoại lệ dấu chấm động và mô hình ngoại lệ C++ có điểm chung là từ "ngoại lệ". Trên mỗi máy tôi làm việc trên, một ngoại lệ dấu chấm động không ném một ngoại lệ C++.

Ngoài ra, bất kỳ ý tưởng tuyệt vời nào về cách ngăn chặn chia cho 0?

  1. Câu trả lời đơn giản: Đừng làm điều đó.
    Đây là một trong những "Bác sĩ, bác sĩ đau khi tôi làm điều này!" loại tình huống. Vì vậy, không làm điều đó!

  2. Đảm bảo rằng số chia không bằng 0.
    Kiểm tra độ chính xác trên các ước là đầu vào của người dùng. Luôn lọc đầu vào người dùng của bạn cho sự tỉnh táo. Giá trị đầu vào của người dùng bằng 0 khi số được cho là trong hàng triệu sẽ gây ra tất cả các loại havoc ngoài tràn. Do sanity kiểm tra các giá trị trung gian.

  3. Bật ngoại lệ dấu phẩy động.
    Làm cho hành vi mặc định để cho phép lỗi (và đây gần như luôn luôn là lỗi) để bỏ qua là IMHO là một sai lầm lớn trên một phần của ủy ban tiêu chuẩn.Sử dụng mặc định và những infinities và không-một-số cuối cùng sẽ biến mọi thứ thành một Inf hoặc NaN.
    Mặc định là phải dừng các lỗi dấu phẩy động trong các tuyến đường của chúng, với tùy chọn cho phép những thứ như 1.0/0.0 và 0.0/0.0 diễn ra. Đó không phải là trường hợp, vì vậy bạn phải kích hoạt những cái bẫy đó. Làm điều đó và bạn có thể thường xuyên tìm nguyên nhân của vấn đề trong một trật tự ngắn.

  4. Viết phân chia tùy chỉnh, số nhân tùy chỉnh, căn bậc hai tùy chỉnh, hàm tùy chỉnh, ...
    Thật không may là tuyến đường mà nhiều hệ thống phần mềm quan trọng về an toàn phải thực hiện. Đó là một nỗi đau của hoàng gia. Tùy chọn # 1 là ra bởi vì nó chỉ là suy nghĩ mơ ước. Tùy chọn # 3 là do hệ thống không thể được phép sụp đổ. Tùy chọn # 2 vẫn là một ý tưởng tốt, nhưng nó không phải lúc nào cũng hoạt động vì dữ liệu xấu luôn có một cách để lẻn vào. Đó là luật của Murphy.

BTW, vấn đề hơi tồi tệ hơn chỉ chia cho 0. 10 /10 -200 cũng sẽ tràn.

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