6

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

У меня есть этот код на 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 бит.

  • Error: User Rate Limit Exceeded

    от 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
  • похоже проблема в char x, я использовал uint64_t и работает хорошо.

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

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

  • 20

    Так как

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

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