Reputation: 49
I wrote a simple function in C++ to calculate the volume of a Box object which has a length, breadth, and height. This is part of a class, so l,b,h
are private members:
long long CalculateVolume(){
return l*b*h;
}
This does not work correctly with large values of l,b,h
. In my case l = 1039, b = 3749, h = 8473
. The result was
-1355615565
I thought this was due to overflow, so I tried
unsigned long long CalculateVolume(){
return l*b*h;
}
but the result was
18446744072353936051
Finally, what worked was to multiply the integers in steps:
long long CalculateVolume(){
long long result = l;
result *= b;
result *= h;
return result;
}
which gave the correct result of 33004122803
. I don't understand why this solution works. Can you explain what happens under the hood in each of the three cases? Thank you!
Upvotes: 2
Views: 991
Reputation: 71
I think that the types of your 3 variables:l, b, and h are responsible for the wrong behavior, if they are integers values, their multiplication is an integer as well. So you have to cast them to long long or unsigned long long before multiplying. Or like you did in the last snippet of code, you can cast only one of them and then the multiplication will have the biggest type between the factors (which is in that case long long)
Upvotes: 0
Reputation: 60208
If you variables l
, b
, and h
are long long
then the behaviour of both snippets would be identical.
However, if the variables are int
s, then in the first snippet
return l * b * h;
would result in an overflow. The conversion to long long
would only happen when the result is returned, which is too late.
In this snippet
long long result = l;
result *= b; // multiplying 'int' and 'long long' is like multiplying 2 'long long's
result *= h;
return result;
you are only ever multiplying long long
s, so you don't overflow.
You could make your variables long long
to begin with, or cast the variables before multiplying.
Upvotes: 4