2012-02-19 40 views
24

Tôi đã tìm thấy sự không thống nhất khá lạ giữa hành vi của div/.Chia cho số không ở Haskell

*ghci> :t 1 `div` 0 
1 `div` 0 :: Integral a => a 
*ghci> :t 1/0 
1/0 :: Fractional a => a 
*ghci> 1/0 
Infinity 
*ghci> 1 `div` 0 
*** Exception: divide by zero 

Tôi đã khá ngạc nhiên khi nhận thấy rằng việc phân chia phân số cho số không dẫn đến Infinity, trong khi div một cách chính xác dẫn đến một ngoại lệ. A NaN cũng có thể được chấp nhận cho /, nhưng tại sao Infinity? Không có lý giải toán học nào cho kết quả như vậy. Bạn có biết lý do cho việc này không?

+3

Về mặt toán học, có kết quả của '1/0' là' Infinity' là hoàn toàn hợp lý. Nó không phải là giá trị trả lại chính đáng duy nhất, mà là giá trị có ý nghĩa nhất. Lưu ý rằng bạn cũng sẽ nhận được lỗi 'chia cho số không' nếu bạn đánh giá' 1/0 :: Rational'. –

+5

@ DanielFischer: Tôi sẽ không gọi nó là "toán học hoàn toàn hợp lý", vì kiểu nén này (với cực dương và âm) phá hủy khá nhiều định lý giữ ℝ, và một số giả định trong nhiều chương trình. – leftaroundabout

+1

Bạn không nên giả định những thứ như thế khi làm việc với các số dấu phẩy động. Ngay cả các tính chất cơ bản như kết hợp không nhất thiết phải giữ. Bình đẳng cũng không phản xạ cho 'NaN' (Ví dụ '(0/0)/= (0/0)' –

Trả lời

41

Lý do mà div không trả lại Infinity là đơn giản - không có đại diện cho vô cùng trong loại Integer.

/ trả về Infinity vì nó tuân theo chuẩn IEEE 754 (mô tả số đại diện cho số dấu phẩy động) vì loại mặc định FractionalDouble. Các ngôn ngữ khác có số dấu phẩy động (ví dụ: JavaScript) cũng thể hiện hành vi này.

Để làm cho các nhà toán học co rúm người lại hơn nữa, bạn có được một kết quả khác nhau nếu bạn chia tiêu cực 0, mặc dù thực tế rằng -0 == 0 cho nổi:

Prelude> 1/(-0) 
-Infinity 

Đây cũng là hành vi từ tiêu chuẩn.

Nếu bạn sử dụng một loại phân đoạn khác nhau như Rational, bạn sẽ nhận được hành vi mà bạn mong đợi:

Prelude> 1/(0 :: Rational) 
*** Exception: Ratio.%: zero denominator 

Thật trùng hợp, nếu bạn đang băn khoăn về việc tại sao IntegerDouble là các loại trong câu hỏi khi hoạt động thực tế của bạn không tham khảo chúng, hãy xem cách Haskell xử lý các loại mặc định (đặc biệt là kiểu số) trong report.

Phiên bản ngắn gọn là nếu bạn có loại không rõ ràng từ lớp Num, Haskell trước tiên sẽ thử Integer và sau đó Double cho loại đó. Bạn có thể thay đổi điều này bằng câu lệnh default (Type1, Type2...) hoặc tắt bằng tuyên bố default() ở cấp mô-đun.

+0

Tôi có thể tìm hiểu về câu lệnh 'default' ở đâu? Tôi chưa từng thấy nó trước đây: – amindfv

+1

Phần báo cáo mà tôi liên kết để che nó gần Tôi nghĩ rằng nó cũng được đề cập trong phần giới thiệu Gentle cho Haskell.Tuy nhiên, tôi không chắc chắn có nhiều hơn nó được đề cập ở đây (Trừ khi bạn kích hoạt một số phần mở rộng, nó chỉ liên quan đến các kiểu số và hành xử như tôi đã giải thích .) –

+0

Prelude> 1/(- 0) Lỗi chương trình: {primDivDouble 1.0 0.0} –

6

Tôi hy vọng điều này sẽ giúp:

Prelude> 1/0 
Infinity 
Prelude> -1/0 
-Infinity 
Prelude> 0/0 
NaN 
+0

Cảm ơn ... vâng nó trông giống như một giới hạn đặt theo cách đó. –

3

Fractional là không bằng Float (hoặc đôi) gõ.

Phân số 1/n trong đó n đi tới 0 để giới hạn (n → 0) 1/n = + ∞, giới hạn (n → 0) -1/n = -∞ và điều đó có ý nghĩa.

+0

Tôi nghĩ rằng một ràng buộc 'Fractional' được mặc định là' Double', là một kiểu dấu chấm động. Đọc phần báo cáo tôi đã liên kết. –

+0

Đúng, @TikhonJelvis, trừ khi có một khai báo mặc định nói cách khác, một kiểu mơ hồ với ràng buộc 'Fractional' được mặc định là' Double'. –

5

Có thể không phải như vậy vì lý do toán học. Infinity đôi khi được sử dụng như một "thùng rác": mọi thứ không hoạt động trong hệ thống của chúng tôi một cách sạch sẽ, hãy đặt nó vào đó.

Ví dụ:

Prelude> 10 ** 10 ** 10 
Infinity 

... chắc chắn không phải là toán học hợp lý!

+1

Bạn chưa gặp một nhà tài chính cốt lõi nào! :) – Ingo

+0

@Ingo Lõi cứng như ở số không, một, vô cùng? –

+0

@Daniel Ý tôi là những người đang duy trì một con số như 10^100 không có ý nghĩa vì không có nhiều đối tượng trong vũ trụ. Nhưng có lẽ họ thích 10^10^10 = NaN – Ingo

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