2016-02-01 16 views
5
#include <stdio.h> 

int main() { 
    printf("sizeof(int): %zu\n", sizeof(int)); 
    printf("%d\n", 2147483648u > -2147483648); 
    printf("%d\n", ((unsigned int)2147483648u) > ((int)-2147483648)); 
    printf("%d\n", 2147483648u != -2147483648); 
    printf("%d\n", ((unsigned int)2147483648u) != ((int)-2147483648)); 
    return 0; 
} 

Kết quả của mã này trong cả C và C++, trên cygwin64 và một máy rhel6.4 với gcc 5.2.0 là:Hiểu 2^31 và -2^31 nguyên khuyến mãi

sizeof(int): 4 
1 
0 
1 
0 

Theo "Integer promotions", 2147483648u sẽ thuộc loại unsigned int (ngay cả khi không có hậu tố u) và -2147483648 loại int (như thường lệ). Tại sao các kết quả khác nhau bằng cách truyền rõ ràng?

Theo "Usual arithmetic conversions", đoạn này được áp dụng:

Nếu không, signedness là khác nhau: Nếu toán hạng với loại unsigned có hơn rank chuyển đổi hoặc bằng so với thứ hạng của loại các toán hạng ký, sau đó các toán hạng với ký kiểu là mặc nhiên được chuyển đổi để loại unsigned

Điều này có nghĩa rằng kết quả đúng là như thể:

2147483648u > 2147483648u 
2147483648u != 2147483648u 

được thực hiện, vì trong 32 bit, ký -2^31 và dấu 2^31 có cùng biểu diễn. Nói cách khác, kết quả với phép đúc là chính xác. Chuyện gì vậy?

Tôi có cảm giác bằng cách nào đó, quảng cáo số nguyên cấp cao hơn được áp dụng mà không cần truyền, vì vậy tôi nhận được ví dụ: một quảng cáo được ký kết 64 bit trên cả hai mặt - nhưng tại sao?

Cả hai tệp thi hành đều được biên dịch dưới dạng 64 bit, điều này có thể đóng một vai trò không?

+0

Vui lòng chọn một trong C và C++. Hai ngôn ngữ này khác nhau và câu trả lời có thể khác nhau cho cả hai ngôn ngữ. – fuz

+2

@FUZxxl: Không phải, trong trường hợp này. – DevSolar

+0

Ngoài ra, bạn đang biên soạn chuẩn C nào? Xử lý các hằng số nguyên thay đổi trong C11. – fuz

Trả lời

12

Không có hằng số nguyên âm. Chỉ có những cái tích cực với toán tử - đơn nhất được áp dụng.

Kể từ 2147483648 > INT_MAX, mà khuyến khích 2147483648 đến lớn tiếp theo ký (vì bạn đã không thêm u) kiểu số nguyên, trước các - được áp dụng.


Bằng cách này, đó là lý do tại sao INT_MIN thường được định nghĩa như (-INT_MAX - 1) trong <limits.h>. ;-)

+1

Wow, điều này không bao giờ đánh tôi trong khoảng 17 năm mã hóa trong c/C++ :-) – Irfy

+0

Trong trường hợp * my *, tôi may mắn và đó là trường hợp. Tuy nhiên win64 dài là 4 byte, vì vậy nếu tôi đã làm điều đó với một trình biên dịch VC, nó sẽ không có được trường hợp. – Irfy

+0

Nếu bạn đang cố gắng đạt đến giới hạn, hãy thử nhập -2^63 và -2^127 (được tính) dưới dạng chữ :) – Irfy

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