Elena
Elena

Reputation: 49

C++ integer multiplication: explain this behaviour

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

Answers (2)

Ghassen Ben Hamida
Ghassen Ben Hamida

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

cigien
cigien

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 ints, 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 longs, so you don't overflow.

You could make your variables long long to begin with, or cast the variables before multiplying.

Upvotes: 4

Related Questions