Divyaanand Sinha
Divyaanand Sinha

Reputation: 396

Wrong answer in C for long number calculations

long int k=(long int)(2000*2000*2000);

the above calculation is giving me wrong answer in C. What is wrong?

Upvotes: 0

Views: 2007

Answers (5)

Tom Karzes
Tom Karzes

Reputation: 24102

You can't just multiply the values together as ordinary precision integers and then cast the result to a higher precision, because the result has already overflowed at that point. Instead, the operands need to be higher precision integers before they're multiplied. Try the following:

#include <stdio.h>

int main(void)
{
    long long int n = (long long int)2000*(long long int)2000*(long long int)2000;
    printf("long long int operands: %lld\n", n);

    return 0;
}

On my machine, this gives:

long long int operands: 8000000000

Upvotes: 0

Holt
Holt

Reputation: 37661

There are two problems in your code:

  1. long int is (on most architecture) not enough to store 8e9.
  2. When you do 2000 * 2000 * 2000, operations are made using "simple" int, thus, int * int * int = int so you cast the result to an int and then to a long int.

You need to use long long int and specify that you want long long int:

long long int k = 2000LL*2000LL*2000LL;

Notice the extra LL after 2000 saying "It's 2000, but as a long long int!".

Upvotes: 1

nwellnhof
nwellnhof

Reputation: 33658

If a C integer constant fits in an int, it is of type int. So your expression is evaluated as:

long int k = (long int)((int)2000*(int)2000*(int)2000);

If int isn't large enough to hold the result of the multiplication, you'll get a signed integer overflow and undefined behavior. So if long is large enough to hold the result, you should write:

long k = 2000L * 2000L * 2000L;

The L suffix forces the type of the literal to long (long is equivalent to long int).

But on most platforms, even long is only a 32-bit type, so you have to use long long which is guaranteed to have at least 64 bits:

long long k = 2000LL * 2000LL * 2000LL;

The LL suffix forces the type of the literal to long long.

Upvotes: 3

Peter
Peter

Reputation: 36617

2000 is of type int, so 2000*2000*2000 is also of type int.

Assuming a 32-bit int (which is actually more than the standard requires, since an int is not required by the standard to represent a value more than 32767) the maximum representable value is about 2,147,483,647 (commas inserted for readability) which is less than 8,000,000,000.

You will probably want to do the calcuation as 2000LL*2000*2000 which takes advantage of multiplication being left-right associative, and will promote all the 2000 values to long long int before doing the multiplication. Your variable will also need to be of type long long int if you want a guarantee of being able to store the result.

Upvotes: 2

gsamaras
gsamaras

Reputation: 73424

Holt's answer is the correct one, I am just leaving this here as caveat!


You could try to use:

long long int

instead of

long int

However, in my local machine, it has no effect:

#include <stdio.h>

int main(void)
{

    long int k=(long int)(2000*2000*2000);
    printf("With long int, I am getting: %ld\n", k);

    long long int n = 2000*2000*2000;
    printf("With long long int, I am getting: %lld\n", n);

    return 0;
}

Output:

With long int, I am getting: -589934592
With long long int, I am getting: -589934592

Warnings:

../main.c:6:36: warning: integer overflow in expression [-Woverflow]
     long int k=(long int)(2000*2000*2000);
                                    ^
../main.c:9:32: warning: integer overflow in expression [-Woverflow]
     long long int n = 2000*2000*2000;

Even this:

unsigned long long int n = 2000*2000*2000;
printf("With long long int, I am getting: %llu\n", n);

will overflow too.

Upvotes: 1

Related Questions