Вопрос по 64bit, c – C сдвиг влево на 64 бит сбой

6

У меня есть этот код на C (он предназначен только для изучения):

    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);        
    }       

Что напечатано:

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

Почему в x & gt; 26 у меня есть эти странные ценности? Я в gcc 4.6.1 в Ubuntu 10.10 64 бит.

похоже проблема в char x, я использовал uint64_t и работает хорошо. Frederico Schardong
Вы сможете увидеть, что происходит более четко, еслиtotal = (((((1 << x) * x) / 64) + 1) * sizeof(uint64_t)); упрощается доtotal = ((1 << x) * x); затем напечатан сprintf("%d - 0x%llx\n", x, total); вы увидите, что бит знака превратится в отрицательный nmber, который печатается как огромное число с помощью printf (& quot; ... -% llu \ n & quot ;, ... total); gbulmer

Ваш Ответ

2   ответа
20

1 являетсяint32 бита, так(1 << 27)*27 переполняется. использование1ull.

Что касается вашего комментария, еслиx этоuint64_t, затем1 << x все ещеint, но для умножения это будет приведено кuint64_tтак что переполнения не будет. Однако еслиx >= 31, 1 << x будет неопределенным поведением (поскольку результирующее значение не может быть представлено 32-битным целочисленным типом со знаком).

Error: User Rate Limit Exceeded Frederico Schardong
0

ваша проблема в том, что вы рассчитываете с 32-битным и назначаете его позже на 64-битное значение

деление на 64 такое же, как не сдвиг 6 бит

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);        
}

еще не скомпилировано

Похожие вопросы