Sweetgirl17
Sweetgirl17

Reputation: 97

How do I prevent integer overflow when using C or C++?

http://ideone.com/hANuZ

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

When I compile and run this piece of code, weird stuff happens when I print 'value' after it is larger than 2^30, even when I declare it as an unsigned long.

What do I do? I am simply a beginner. :-(

Upvotes: 2

Views: 10329

Answers (4)

Yanick Rochon
Yanick Rochon

Reputation: 53616

Just for fun, I did modify your code example a little for clarity

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

You'll notice that 127 is 8 bit and 256 is 9 bit. This is because

127 =   1000 0000
256 = 1 0000 0000

Also, 2^32 is 0 because

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

Upvotes: 1

sje397
sje397

Reputation: 41862

The simple answer would be to try declaring it as an unsigned long long which is larger than 32 bits (minimum 64 bits according to the standard, thx @caf).

When dealing with types where the specific size is important though, you should use a type with a known size, like int64_t.

Upvotes: 2

JohnKlehm
JohnKlehm

Reputation: 2398

If you need integer precision you need to use an external library for larger numbers. For C GMP http://gmplib.org/ is a well known library. If you don't need integer precision just use a float or a double.

If you're curious about what the limits are based on for types, this page is an ok read up http://www.lix.polytechnique.fr/~liberti/public/computing/prog/c/C/CONCEPT/data_types.html.

Upvotes: 0

Foo Bah
Foo Bah

Reputation: 26281

You are printing it like it is a signed integer. try using the format string

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

check your printf documentation for all of the formatting codes and what they do. %u is for unsigned int. unsigned long is generally %lu

Upvotes: 4

Related Questions