2010-06-08 45 views
5

Tôi biết, Int32.MaxValue * Int32.MaxValue sẽ mang lại số lớn hơn Int32; Nhưng, không nên tuyên bố này đưa ra một loại ngoại lệ nào đó?Tại sao Int32.MaxValue * Int32.MaxValue == 1?

Tôi đã thực hiện việc này khi thực hiện một việc như IF (X * Y > Z) trong đó tất cả đều là Int32. XY đủ lớn, bạn nhận được giá trị không có thật từ X * Y.

Tại sao lại như vậy và cách thực hiện việc này? bên cạnh việc truyền mọi thứ tới Int64.

+0

Đây có phải là trong một 'khối unchecked'? – Skywalker

+0

Xem http://stackoverflow.com/questions/2363838/when-must-we-use-checked-operator-in-c –

Trả lời

6

Bạn đã vô hiệu hóa kiểm tra tràn trong dự án của bạn. Với chế độ được chọn Trên nó sẽ ném một ngoại lệ.

+0

cảm ơn bạn đã trả lời! Tôi không tắt kiểm tra tràn; cài đặt này ở đâu trong Visual Studio? –

+0

Tôi sẽ không có một bản sao của VS ở đây nhưng nếu tôi nhớ rõ nó trong các tùy chọn trình biên dịch nâng cao (Nhấp chuột phải vào một dự án và sau đó Properties -> Build -> Advanced) – munissor

19

Theo mặc định, C# số học được thực hiện trong một ngữ cảnh không được kiểm soát, có nghĩa là giá trị sẽ cuộn qua.

Bạn có thể sử dụng checked and unchecked keywords để kiểm soát hành vi đó.

+0

Chỉ cần chạy vào một kịch bản mà int.maxvalue + 1 là int.minvalue ...Tôi đã gãi đầu của tôi khó khăn như vậy với một cho đến khi nhận ra nó phải được cán qua! – richard

6

Bạn phải yêu cầu nó:

checked { 
    int a = int.MaxValue; 
    int b = int.MaxValue; 
    int c = a * b; // kaboom 
} 
26

Bởi vì ranh giới int32 kết quả cho 32bits.

Vì vậy, nếu bạn xem xét toán ở cấp độ byte.

FFFFFFFF * FFFFFFFF = FFFFFFFE00000001 

Như bạn thấy, mức thấp nhất 4 byte = 1.

2

Int32.MaxValue (sử dụng giá trị được cung cấp here) là 2.147.483.647.

Trong cơ sở 2, đó là: 111 1111 1111 1111 1111 1111 1111 1111 ... 2^31-1. Bit đầu tiên là bit dấu.

Nếu bạn nhân rằng bằng cách riêng của mình, bạn sẽ có được: 11 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 0000 0000 0000 0000 0001

Trở lại với vấn đề ban đầu của "tại sao nó 1?", Vì Integer.MaxValue là giá trị lớn nhất, gây ra một lỗi tràn số nguyên. Kết quả được cắt ngắn xuống 31 bit thấp nhất, tất cả là 0 cộng với 1.

Chỉnh sửa: Đây là a tutorial trên phép nhân nhị phân. Sử dụng một trường hợp đơn giản của tất cả các 1s: * 111

bạn nhận được: + 11100 = 100001

Bạn có thể mở rộng này đối với trường hợp Int32.MaxValue. Tôi rút ngắn nó xuống còn 3 chữ số cho ngắn gọn.

Ngoài ra, như một câu trả lời khác đã nói, trong C#, các lỗi này sẽ xảy ra theo mặc định.

+0

Một điều trị tốt cho Nghìn người cần nó, nhưng OP đã tự hỏi tại sao C# không bắt nó và ném một lỗi. – BCS

8

Thật thú vị khi lưu ý rằng các công trình này không phụ thuộc vào cơ sở bạn sử dụng:

(n-1)*(n-1) mod n 
n^2 - 2n + 1 mod n 
0 - 0 + 1 mod n 
      1 mod n 
Các vấn đề liên quan