2010-01-13 65 views
49

Tôi đã có trải nghiệm kỳ lạ này với vấn đề số 10 trên Project Euler (trang web tuyệt vời bằng cách này). Nhiệm vụ là tính toán tổng của tất cả các số nguyên tố dưới hai triệu.Không có ngoại lệ tràn cho int trong C#?

Tôi đã sử dụng hàm int cho tổng, và thuật toán của tôi đã tạo ra câu trả lời, nhưng khi tôi dán nó để xác minh câu trả lời, nó đã sai.

Hóa ra là kết quả quá lớn để vừa với một int, nhưng điều này không gây ra lỗi tràn hay gì đó? Thay vào đó, nó chỉ trả về một giá trị xa so với câu trả lời thực sự.

Khi tôi thay đổi loại thành dài, tất cả mọi thứ đều là tài xế hunky.

+5

Bạn có thực sự muốn mọi hoạt động số nguyên để kiểm tra tràn? –

+4

Vâng, nó shure đã có thể tiết kiệm cho tôi một số thời gian trong trường hợp cụ thể này;) – erikric

+1

Trong trường hợp này, có. Đại đa số các hoạt động không thể tràn qua mặc dù. Nó sẽ là thú vị nếu trình biên dịch có thể chứng minh điều này và vô hiệu hóa kiểm tra như là một kết quả, nhưng tôi rất nhiều nghi ngờ nó. – Thorarin

Trả lời

73

Hoạt động C# số nguyên không ném ngoại lệ khi tràn theo mặc định. Bạn có thể đạt được điều đó thông qua cài đặt dự án hoặc bằng cách thực hiện phép tính checked:

int result = checked(largeInt + otherLargeInt); 

Bây giờ hoạt động sẽ bị ném.

Ngược lại là unchecked, điều này khiến mọi hoạt động không được chọn một cách rõ ràng. Rõ ràng, điều này chỉ có ý nghĩa khi bạn đã bật các hoạt động đã kiểm tra trong cài đặt dự án.

+0

Trừ khi bạn đang ở chế độ gỡ lỗi, nơi tôi nghĩ rằng các hoạt động int được kiểm tra theo mặc định. – Ant

+5

Không. Tôi chạy trong chế độ gỡ lỗi khi điều này xảy ra. – erikric

+0

Ồ. Tôi đứng sửa. Tôi đã chắc chắn rằng các dự án Project Euler của tôi đã nói với tôi về các luồng tràn trong chế độ gỡ lỗi.:/ – Ant

19

Trong C# an OverflowException không được ném (trong VB ngoại lệ được ném theo mặc định).

Để có được excpetion bạn phải nhúng mã của bạn trong một bối cảnh checked:

byte value = 241; 
checked 
{ 
    try 
    { 
     sbyte newValue = (sbyte) value; 
     Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", 
      value.GetType().Name, value, 
      newValue.GetType().Name, newValue); 
    } 
    catch (OverflowException) 
    { 
     Console.WriteLine("Exception: {0} > {1}.", value, SByte.MaxValue); 
    } 
}  

MSDN giải thích chi tiết hơn:

Đối với số học, đúc, hoặc chuyển đổi hoạt động để ném một Tràn thừa, hoạt động phải xảy ra trong ngữ cảnh được chọn. Theo mặc định , phép tính số học và tràn trong Visual Basic được chọn; trong C#, chúng không có. Nếu hoạt động xảy ra trong ngữ cảnh không được kiểm tra, kết quả bị cắt bớt bằng cách loại bỏ bất kỳ bit đặt hàng cao nào không phù hợp với loại đích.

6

tôi đã thêm cmt, nhưng nó có lẽ thú vị cho một số bạn:

msdn cho chúng ta biết:

Integer số học tràn hoặc ném một OverflowException hoặc vứt bỏ nhiều nhất các bit quan trọng của kết quả

nhưng

Luồng số học thập phân luôn ném phát hiện tràn.

cũng

Khi số nguyên tràn xảy ra, những gì xảy ra phụ thuộc vào việc thực hiện bối cảnh, có thể được kiểm tra hoặc không được kiểm soát. Trong ngữ cảnh được chọn, một trường hợp ngoại lệ bị tràn. Trong một ngữ cảnh không được kiểm soát , nhiều nhất các bit quan trọng của kết quả là bị loại bỏ và thực thi tiếp tục. Vì vậy, C# cho bạn lựa chọn xử lý hoặc bỏ qua tràn.

+0

Điều đó có ý nghĩa, vì số thập phân chủ yếu được sử dụng cho tiền tệ hoặc tính toán khoa học, và bạn có thể sẽ yêu cầu họ ném chúng xuống âm thầm. – Snellface

6

Theo mặc định, C# không kiểm tra lỗi số học trên các số nguyên. Bạn có thể thay đổi điều này bằng /checkedcompiler option hoặc bằng cách bật "Kiểm tra lỗi tràn/số học" trong Visual Studio (thuộc tính dự án - Xây dựng - Nâng cao).

Bạn có thể sử dụng checked and unchecked keywords để ghi đè mặc định theo từng trường hợp. Nếu bạn dựa vào việc kiểm tra diễn ra trong một đoạn mã, hãy bật nó một cách rõ ràng bằng cách sử dụng checked sẽ là một ý tưởng hay.

int j = checked(i * 2); 

checked 
{ 
    int j = i * 2; 
    // Do more stuff 
} 

Lưu ý rằng hoạt động điểm nổi bao giờ ném một OverflowException, và các hoạt động thập phân luôn ném một OverflowException. Xem thêm C# operators.

9

Đó là bởi vì, theo mặc định C# không ném bất kỳ ngoại lệ nào cho tràn số nguyên cũng như tràn. Có vài điều bạn có thể làm ở đây.

Lựa chọn 1

Bạn phải kích hoạt các ngoại lệ được ném bởi đi đến dự án => properties => Xây dựng tab => Advanced => kiểm tra số học tràn underflow. (Chắc chắn rằng bạn đánh dấu vào tùy chọn)

enter image description here

Hãy chắc chắn rằng bạn đánh dấu vào tùy chọn

Tùy chọn 2

Sử dụng khối đã chọn và ném ngoại lệ tràn để xử lý tình huống. Một đoạn mã mẫu sẽ

 try 
     { 
      checked 
      { 
       int y = 1000000000; 
       short x = (short)y; 
      } 
     } 
     catch (OverflowException ex) 
     { 
      MessageBox.Show("Overflow"); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Error"); 
     } 

Hy vọng điều này sẽ giúp bạn ... :)

+2

Tùy chọn 1 là điểm then chốt mà nhiều người không biết. Bạn nhận được +1 của tôi. – RBT

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