Reputation: 396
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
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
Reputation: 37661
There are two problems in your code:
long int
is (on most architecture) not enough to store 8e9
.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
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
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
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