c++long-long

C++ calculation of long long with int


below you can find a part of my C++ code of a box class. When I want to calculate the volume for

l=1039 b=3749 h=8473

I am expecting 33004122803. Unfortunately I do not understand why only the first implementation (CalculateVolume1) gives the correct answer.

The other two calculations result in -1355615565. Can someone please help me to understand why this is the case?

    class Box{

    private:

    int l,b,h;

    public:
    //works
    long long CalculateVolume1() { return (long long) l*b*h;} 
    // does not work
    long long CalculateVolume2() { return long long v = l*b*h;} 
    //does not work
    long long CalculateVolume3() 
    { 
    long long v = long long (l)* long long(b)* long long (h);
    return v;
    }
    };

Solution

  • In the first one, (long long) l*b*h, the cast applies to l, as if it had been written ((long long)l)*b*h. So l gets converted to long long. And since one of the factors in the multiplication is long long, the other two are promoted to long long and the result of the multiplication is correct.

    "Fixing" the syntactic errors in the second and third,

    long long v = l*b*h;
    

    here, the type of all three factors is int, so the multiplication is done on ints, and the result overflows.

    long long v = (long long)l*(long long)b*(long long)h;
    

    this is essentially the same as the first: all three factors are promoted to long long, this time by explicit casts on all three, so the result is calculated using long long arithmetic, and the result fits.

    The problem with the second one as written is that you can't define a variable inside a return statement. So

    return long long v = l; // illegal
    

    should be:

    long long v = l;
    return v;
    

    The problem with the third one as written is that a function-style cast has to have a name that's a single word:

    long long v = int(l); // okay, but pointless
    long long v = long long(l); // error, invalid name
    

    could be:

    typedef long long my_type;
    long long v = my_type(l); // okay