我不明白为什么这个解决方案有效。 (整数溢出)

I dont understand why this solution worked. (Integer Overflow)

抱歉标题不好,但我不知道如何命名。 我已经解决了一些练习问题,我遇到了这个问题。挑战是为一个盒子写一个 class。所以它有经度、高度和宽度。其中一种方法应该 return 盒子的体积。这就像它的简历:

#include<bits/stdc++.h>

class Box {
private:
    int l,b,h;
public:
    Box(int L, int B, int H){
        l=L;b=B;h=H;
    }
    int CalculateVolume() {
        return b*l*h;
    } 
};

int main() {
    int l,b,h;
    std::cin << l << b << h;
    Box box(l, b, h);
    std::cout << box.CalculateVolume() << std::endl;
}

然后到了测试用例的时候,它给了我一个错误。

Input: 1039 3749 8473
Output: -1355615565

所以我说,好吧,结果太大了。让 return 类型变大。

    long long int CalculateVolume() {
        return b*l*h;
    } 
// No changes to the rest

结果是一样的,所以我说:“好的,更大一点”然后这样做:

    unsigned long long int CalculateVolume() {
        return b*l*h;
    } 
// No changes to the rest
Input: 1039 3749 8473
Output: 18446744072353936051

令我高兴的是,我发现结果不是负面的。但是用我的计算器检查结果也不正确。所以我将它存储在一个变量中以查看发生了什么。

    unsigned long long int CalculateVolume(){
        unsigned long long int volume = b*h*l;
        std::cout << volume << std::endl;
        return volume;
    } 
// No changes to the rest
Input: 1039 3749 8473
Output: 
18446744072353936051
18446744072353936051

我对输出结果并不感到惊讶。在最后的努力中,我真的不知道这个想法是从哪里来的,我这样做了:

    unsigned long long int CalculateVolume(){
        unsigned long long int volume = b*h;
        unsigned long long int a = volume * l;
        return a;
    } 
// No changes to the rest

令我惊讶的是我得到了正确答案

Input: 1039 3749 8473
Output: 33004122803

但是我真的不明白为什么。最重要的是,我是否应该在我的程序中这样做,以防它必须处理非常大的数字?或者我该如何处理?

非常感谢您的帮助。

TIL 如果变量是整数,则将运算结果分配给 long long int 并不重要,运算将使用 int 数学来完成。

所以我使用的临时解决方案是因为 b*h 仍然是一个没有问题的整数,然后当我将它乘以 l 时,它已经将它们作为 long long int 进行操作。这将是最终解决方案:

#include<bits/stdc++.h>

class Box {
private:
    long long int l,b,h;
public:
    Box(int L, int B, int H){
        l=L;b=B;h=H;
    }
    long long int CalculateVolume() {
        return b*l*h;
    } 
};

int main() {
    int l,b,h;
    std::cin >> l >> b >> h;
    Box box(l, b, h);
    std::cout << box.CalculateVolume() << std::endl;
}

再次感谢您的帮助。