2011-08-09 1 views
1

http://ideone.com/hANuZКак предотвратить переполнение целых чисел при использовании C или C++?

#include <stdio.h> 
int main(int argc, char *argv[]) { 
    /** 
    * Prints out powers of 2 for 32 iterations. 
    */ 
    int iterations = 0; 
    int value = 1; 
    while (iterations <= 32) { 
     // Prints in this format: iterations 2^n value 
     printf("%d\t2^%d\t%d", iterations, iterations, value); 
     switch (iterations) { 
      case 8: 
      case 16: 
      case 32: 
       printf("\t\t%d bit\n", iterations); 
       break; 
      default: 
       printf("\n"); 
       break; 
     } 
     value *= 2; 
     ++iterations; 
    } 
    return 0; 
} 

Когда я скомпилировать и запустить этот кусок кода, странные вещи происходят, когда я печатаю «значение» после того, как он больше, чем 2^30, даже когда я объявляю его как беззнаковое долго.

Что мне делать? Я просто новичок. :-(

+3

на самом деле, это работает 33 итераций –

+0

может быть, потому что я использовал ++ итерации? – Sweetgirl17

+0

hmm .... 0-32 = 33. Вы инициализируетесь до 0 и выполняете цикл до тех пор, пока не будет = = 32, поэтому он пройдет в цикле 33 раза –

ответ

4

Вы печатаете его, как это знаковое целое. Попробуйте использовать строку формата

"%u\t2^%u\t%u" 

проверить документацию PRINTF для всех кодов форматирования и что они делают. %u для unsigned int. unsigned long обычно %lu

+0

, это избаловлено от знака на 2^31 на 31-й итерации – Sweetgirl17

+0

только последний может быть «% u», первые два являются переменными «итерации» и могут быть «% d» в порядке –

+0

@ Sweetgirl17, 32-я итерация. Ваша первая итерация равна ** 0 **, поэтому, когда «итерации» равно 31, вы находитесь на своем 32-м. –

1

простой ответ был бы попробовать объявить его как unsigned long long, который больше, чем 32 бита (минимум 64 бит в соответствии со стандартом, ТНХ @caf).

При работе с типами, в которых конкретный размер важен, вы должны использовать тип с известным размером, например int64_t.

+0

'unsigned long long' * определенно * больше 32 бит: требуется не менее 64 бит. – caf

+0

@caf: Я думал, что это просто должно быть больше, чем 'long'. Ta. – sje397

+0

Он должен быть равен или больше, чем 'long', и не менее 64 бит. Оба 'long' и' long long', составляющие 64 бита, соответствуют, и на самом деле являются общими для 64-битных POSIX-систем. – caf

0

Если вам нужна целая точность, вам нужно использовать внешнюю библиотеку для больших чисел. Для C GMP http://gmplib.org/ - хорошо известная библиотека. Если вам не нужна целая точность, просто используйте float или double.

Если вам интересно, какие ограничения основаны на типах, эта страница читается нормально http://www.lix.polytechnique.fr/~liberti/public/computing/prog/c/C/CONCEPT/data_types.html.

1

Просто для удовольствия, я изменить ваш пример кода немного для ясности

#include <stdio.h> 

int bitcount(unsigned long i) { 
    int count = 0; 
    while (i > 0) { 
     count++; 
     i>>=1; 
    } 
    return count; 
} 

int main(int argc, char *argv[]) { 
    /** 
    * Prints out powers of 2 for 32 iterations. 
    */ 
    int iterations = 0; 
    int value = 1; 
    while (iterations <= 32) { 
     // Prints in this format: iterations 2^n value 
     printf("%d\t2^%u\t%u\t\t%d bit\n", iterations+1, iterations, value, bitcount(value)); 
     value *= 2; 
     ++iterations; 
    } 
    return 0; 
} 

Вы заметите, что 127 является 8 bit и 256 является 9 bit. Это происходит потому, что

127 = 1000 0000 
256 = 1 0000 0000 

Также 2^32 является 0 потому

2^32 = 1 0000 0000 ... 0000 0000  (overflow for int) 
    = 0000 0000 ... 0000 0000 = 0 (only the first 32 bits are preserved)