2012-09-21 37 views
14

Tôi có một bài kiểm tra vào ngày mai và tôi không thể hiểu cuốn sách giải thích của tôi, tôi đánh giá cao sự giúp đỡ:Java Số nguyên MIN_VALUE tiêu cực sau đó so sánh

public class TestClass{ 
     public static void main(String[] args) throws Exception{ 
      int a = Integer.MIN_VALUE; 
      int b = -a; 
      System.out.println(a+ " "+b); 
     } 
} 

Output: -2147483648 -2147483648

Tại sao in này 2 số âm của cùng một cường độ và không phải là một tích cực và tiêu cực?

Trả lời

30

Do tràn số nguyên im lặng: Integer.MIN_VALUE-2^31Integer.MAX_VALUE2^31-1, vì vậy -Integer.MIN_VALUE2^31, đó là Integer.MAX_VALUE + 1, mà theo định nghĩa là quá lớn đối với một số nguyên. Vì vậy, nó tràn và trở thành Integer.MIN_VALUE ...

Bạn cũng có thể kiểm tra xem:

System.out.println(Integer.MAX_VALUE + 1); 

in điều tương tự.

về mặt kỹ thuật hơn, kết quả được xác định bởi Java Language Specification #15.18.2:

Nếu một tràn số nguyên Ngoài ra, sau đó kết quả là các bit bậc thấp của tổng toán học như đại diện trong một số định dạng two's-bổ sung đủ lớn . Nếu tràn xảy ra, thì dấu của kết quả không giống như dấu của tổng toán học của hai giá trị toán hạng.

+0

Nhanh và chính xác! –

+0

Ah cuốn sách của tôi đã cho tôi một lời giải thích trong nhị phân, tôi rất thích lời giải thích này mà tôi có thể hiểu dễ dàng hơn. Nhiều đánh giá cao. – Quinma

+1

Một cách khác để nhận ra vấn đề này là khi sử dụng 'Math.abs()'. 'Math.abs (Integer.MIN_VALUE) == Integer.MIN_VALUE' – whiskeyspider

3

Về cơ bản, bởi vì Integer.MAX_VALUE thực sự chỉ là 2147483647, vì vậy -Integer.MIN_VALUE, đó sẽ là 2147483648, thực sự tràn năng lực của các đại diện nhị phân bên trong của số nguyên. Do đó, kết quả "lặp lại" trở lại Integer.MIN_VALUE, hoặc -2147483648.

Nếu bạn đã thực hiện long b = -((long)a); thay vào đó, bạn sẽ nhận được kết quả mong đợi.

1

Để hiển thị này thậm chí rõ ràng hơn:

<br> 
Integer.MIN_VALUE is -2^31 = -2147483648<br> 
Integer.MAX_VALUE is 2^31-1 = 2147483647 
/*notice this is 1 less than the negative value above*/ 
<br> 

1Integer.MAX_VALUE không thể lấy 2147483648. Đây là số quá lớn cho số nguyên chính xác 1. Điều này làm cho số trở lại trên thang tỷ lệ từ giá trị lớn nhất trở lại để bắt đầu poing là giá trị nhỏ nhất.