2012-04-06 18 views
6

tôi có mã này trong C (đó là để nghiên cứu chỉ):C thay đổi còn lại trên 64 bit không

char x; 
    uint64_t total = 0; 

    for(x = 20; x < 30; x++){ 
     total = (((((1 << x) * x)/64) + 1) * sizeof(uint64_t)); 
     printf("%d - %llu\n", x, total);   
    }  

gì được in:

20 - 2621448 
21 - 5505032 
22 - 11534344 
23 - 24117256 
24 - 50331656 
25 - 104857608 
26 - 218103816 
27 - 18446744073625665544 
28 - 18446744073575333896 
29 - 18446744073508225032 

Tại sao tại x> 26 Tôi phải làm những giá trị lạ? Tôi đang ở gcc 4.6.1 trên Ubuntu 10,10 64 bit.

+0

trông giống như vấn đề là tại char x, tôi đã sử dụng uint64_t cho nó và hoạt động tốt. –

+0

Bạn sẽ có thể thấy điều gì đang xảy ra rõ ràng hơn nếu 'total = (((((1 << x) * x)/64) + 1) * sizeof (uint64_t));' được đơn giản hóa thành 'total = ((1 << x) * x); 'sau đó được in bằng' printf ("% d - 0x% llx \ n", x, tổng số); 'bạn sẽ thấy bit dấu hiệu chuyển số âm nmber, được in thành một số lượng lớn bởi printf ("... -% llu \ n", ... tổng cộng); – gbulmer

Trả lời

18

1int, 32 bit, vì vậy, (1 << 27)*27 bị tràn. Sử dụng 1ull.

Về nhận xét của bạn, nếu x là một uint64_t, sau đó 1 << x vẫn là một int, nhưng đối với nhân nó sẽ được đúc để uint64_t, vì vậy thì sẽ không có tràn. Tuy nhiên, nếu x >= 31, 1 << x sẽ là hành vi không xác định (vì giá trị kết quả không thể được biểu thị bằng loại số nguyên 32 bit đã ký).

+0

Đó là con người! Cảm ơn! –

0

Tôi đoán vấn đề của bạn là, bạn tính toán với 32bit và gán nó sau này đến một giá trị 64 bit

phân chia bởi 64 cũng giống như không thay đổi 6 chút

char x; 
uint64_t one = 1; 
uint64_t total = 0; 

for(x = 20; x < 30; x++){ 
    total = ((((one << (x - 6)) * x) + 1) * sizeof(uint64_t)); 
    printf("%d - %llu\n", x, total);   
} 

không biên soạn chưa