2010-05-03 20 views
15

Tôi đã đọc ở nhiều nơi mà tràn số nguyên được xác định rõ trong C không giống như đối tác đã ký.Câu hỏi về hành vi C đối với dòng số nguyên không dấu

Dòng dưới có giống nhau không?

Ví dụ:

unsigned int x = -1; // Does x == UINT_MAX? 

Cảm ơn.

Tôi không thể nhớ lại ở đâu, nhưng tôi đọc ở đâu đó số học về các loại tích phân không dấu là mô-đun, vì vậy nếu trường hợp đó là -1 == UINT_MAX mod (UINT_MAX + 1).

+2

Tôi tin rằng thuật ngữ "gạch dưới" chỉ thực sự áp dụng cho các số dấu phẩy động, nơi bạn không thể đại diện cho một số số rất gần bằng không. Số nguyên sẽ không có vấn đề này. – WildCrustacean

+0

@bde Tôi đồng ý rằng đó là một tuyên bố về mặt kỹ thuật chính xác, nhưng thuật ngữ này thường bị quá tải do vi phạm điều kiện biên trên đầu cuối của một hệ thống số. – vicatcu

Trả lời

22

§6.2.5, đoạn 9:

Một tính toán liên quan đến unsigned toán hạng có thể không bao giờ tràn, bởi vì một kết quả mà không thể được đại diện bởi kết quả kiểu dữ liệu integer unsigned được giảm modulo số đó là một trong số lớn hơn giá trị lớn nhất mà có thể được biểu thị bằng kết quả là loại .

Edit:

Xin lỗi, tài liệu tham khảo sai, nhưng kết quả vẫn ghìm chặt. Các tài liệu tham khảo chính xác được §6.3.1.3 (có chữ ký và số nguyên unsigned chuyển đổi):

nếu kiểu mới là unsigned, giá trị được chuyển đổi bởi nhiều lần cộng hoặc trừ một hơn giá trị tối đa mà có thể được thể hiện trong loại mới cho đến khi giá trị nằm trong phạm vi loại mới.

Vì vậy, có, x == UINT_MAX.

+0

Tham chiếu của bạn là tốt, nhưng không áp dụng được vì biểu thức -1 liên quan đến toán hạng đã ký, chứ không phải toán hạng chưa ký. –

+0

Câu hỏi đã thừa nhận rằng tràn được xác định rõ. Câu hỏi đặt ra là về số âm, không phải là số dương. –

+0

@Doug, @Mark: Câu hỏi đặt ra là về các chuyển đổi từ các số nguyên đã ký thành unsigned, được chỉ định bởi §6.3.1.3. –

4

-1, khi được biểu thị bằng số bổ sung của 2, số tiền là 0xFF ... F cho số lượng bit của bạn bao nhiêu. Trong không gian số không dấu, giá trị đó là giá trị lớn nhất có thể (nghĩa là tất cả các bit được đặt). Do đó có, x == UINT_MAX. Đoạn mã sau phát ra "1" trên trình biên dịch nghiêm ngặt C99:

#include <stdio.h> 
#include <stdint.h> 
#include <limits.h> 

int main(int argc, char **argv){ 
    uint32_t x = -1;  
    printf("%d", x == UINT_MAX ? 1 : 0); 
    return 0; 
} 
+1

Các số bổ sung cho hai con số có được yêu cầu theo tiêu chuẩn không? –

+4

Không, bổ sung 2s là không cần thiết theo tiêu chuẩn, vì vậy giải pháp này không phải là chung; xem câu trả lời của tôi –

+1

Không bắt buộc giá trị tối đa của 'uint32_t' là' UINT_MAX' - 'UINT_MAX' có thể nhỏ bằng 65535 và lớn bằng' ULONG_MAX'. Nếu bạn thay đổi 'uint32_t' thành' unsigned', nó sẽ đúng. – caf

-1

Bạn đang trộn các số đã ký và chưa ký, không được thực hiện.

unsigned int x = 0u - 1u; // is OK though 
+3

Nó có thể hoặc có thể không được uncool, nhưng nó được xác định hoàn toàn phù hợp tiêu chuẩn C. –

+0

@Stephen Canon, Untrue. Biểu diễn bit của -1 không được xác định. Nó có thể là những bổ sung, ví dụ. –

+0

@Stepen, "tuân thủ tiêu chuẩn" có thể, nhưng "được xác định rõ"? Đó là mấu chốt của câu hỏi. –