pokiman
pokiman

Reputation: 986

Adding large numbers in C

I am a bit confused about the behavior of c when it comes to adding large numbers. This is probably a beginner's question but would appreciate any help.

unsigned long total = 0;
total = 1124073472 + 2835349503;
total += 2533359615;
printf("Total: %u\n", total);

The total which gets printed above is not correct. The first add result is fine but the third add throws the total off. I am thinking it is because of overflow. My question is what is a possible solution? Is there a solution without using third party libraries?

Note: I have tried various data types for total. Some of them are DWORD64, INT64, LONG64 etc.

Thanks in Advance.

Upvotes: 2

Views: 5915

Answers (9)

enam
enam

Reputation: 1177

Well almost(!) everyone is right at there point. I think you can look @ following two page as well. It will really give you some better idea about how you can handle a really BIG numbers :

Upvotes: 1

Jim Balter
Jim Balter

Reputation: 16406

Your code is buggy. You should replace %u with %lu in your printf statement to match the type of total. That is sufficient if you're on a system with 32 bit ints and 64 bit longs. But if you're using some other sort of system, you may need to use unsigned long long as noted in some of the other answers.

Upvotes: 0

Goz
Goz

Reputation: 62323

The following code ought to work under Visual C++:

unsigned __int64 total = 0;
total = 1124073472LL + 2835349503LL;
total += 2533359615LL;
printf("Total: %I64u\n", total);

Upvotes: 0

tr3w
tr3w

Reputation: 343

The code has two problems:

  1. The unsigned long has only 32 bit in 32 bit systems. You need to use long long (and turn on the C99 standar in the compiler settings), or INT64 or something like that.

  2. The %u in the printf format string is for 32 (or less) bit wide numbers. You need to use %llu instead.

Upvotes: 0

zwol
zwol

Reputation: 140540

The mathematical sum of these three numbers is larger than 232, and you're using unsigned long, which is 32 bits wide on Windows (even if you compile your program with 64 bit pointers -- this is a willful violation of C89 on Microsoft's part), so the C and C++ standards specify that it wraps around. The number you get is 1124073472 + 2835349503 + 2533359615 - 232.

If you use a 64-bit type, you have to change the printf format specifier to match. This code will give the mathematically expected answer on a C99-compliant system:

#include <stdio.h>

int main(void)
{
    unsigned long long total = 1124073472 + 2835349503;
    total += 2533359615;
    printf("Total: %llu\n", total);
    return 0;
}

No version of MSVC is C99-compliant, however. I don't know the appropriate type declaration or printf format specifier for MSVC.

Addenda: 1) Addition is not specified to wrap around on overflow for signed types; it's undefined behavior. This most commonly bites people who use signed loop indices when the loop limit is data-dependent. 2) If you were doing math with numbers that could potentially be bigger than 264, even long long would not save you. C and (as far as I know) C++ do not have true "bignum" types; you'll need a third party library.

Upvotes: 3

davidivins
davidivins

Reputation: 320

It is indeed an overflow. You will probably want to create your own "BigNumber" class to perform arithmetic on arbitrarily large numbers. However, I'd recommend using a library if possible. Writing your own "BigNumber" class can be a bit of a chore. Check out the ones posted here - Class for calculating arbitrarily large numbers?

If you don't use them, you can at least use them as guidance.

Upvotes: 0

Henno Brandsma
Henno Brandsma

Reputation: 2166

Have you tried "unsigned long long int"? This will certainly be 64 bits, or use uint64_t, if you have stdint.h. Of course, you could run into new overflow problems (it indeed is that) when you choose even larger numbers, and then it's time to use a bignum library like gmp. And do an overflow check before adding, if you do stick with 64 bit numbers. And use "%lld" to print the decimal result in that case.

Upvotes: 0

Argote
Argote

Reputation: 2155

What you are seeing is indeed because of an overflow but in the print type as others have mentioned since that number fits inside a long.

You will be able to do operations that fit within the long data type. If you want to go larger than that you'd need some sort of "Big Integer" function and if you do not want to use a third party library you can implement your own, however you'd be reinventing the wheel and are better off with using a tested library.

Upvotes: 0

Carl Norum
Carl Norum

Reputation: 224864

You're correct, it's because of overflow. Using a 64-bit type will fix it - you will need to change your printf() format string to printa 64-bit type too, though. Making total an unsigned long long will probably get you a 64-bit type, but the safest way would be to use one of the typedefs from stdint.h. Here's an example program - I also used inttypes.h to get PRIu64.

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main(int argc, char **argv)
{
  uint64_t total = 0;
  total = 1124073472 + 2835349503;
  total += 2533359615;
  printf("Total: %"PRIu64"\n", total);

  return 0;
}

Upvotes: 2

Related Questions