C++ 整数乘法:解释这种行为
C++ integer multiplication: explain this behaviour
我用 C++ 编写了一个简单的函数来计算具有长度、宽度和高度的 Box 对象的体积。这是 class 的一部分,因此 l,b,h
是私有成员:
long long CalculateVolume(){
return l*b*h;
}
这对于 l,b,h
的大值无法正常工作。就我而言 l = 1039, b = 3749, h = 8473
。结果是
-1355615565
我以为这是溢出,所以我试了
unsigned long long CalculateVolume(){
return l*b*h;
}
但结果是
18446744072353936051
最后,有效的方法是逐步将整数相乘:
long long CalculateVolume(){
long long result = l;
result *= b;
result *= h;
return result;
}
给出了 33004122803
的正确结果。我不明白为什么这个解决方案有效。你能解释一下这三种情况中每一种的幕后情况吗?谢谢!
如果变量 l
、b
和 h
是 long long
,那么两个代码段的行为将是相同的。
但是,如果变量是int
s,那么在第一个片段中
return l * b * h;
会导致溢出。到 long long
的转换只会在结果 返回 时发生,但为时已晚。
在此代码段中
long long result = l;
result *= b; // multiplying 'int' and 'long long' is like multiplying 2 'long long's
result *= h;
return result;
你只会乘以 long long
s,所以你不会溢出。
您可以让变量 long long
开始,或者在相乘之前转换变量。
我认为你的 3 variables:l、b 和 h 的类型是导致错误行为的原因,如果它们是整数值,它们的乘法也是整数。所以你必须在相乘之前将它们转换为 long long 或 unsigned long long。或者就像您在最后一段代码中所做的那样,您可以只转换其中一个,然后乘法将具有因子之间最大的类型(在这种情况下为 long long)
我用 C++ 编写了一个简单的函数来计算具有长度、宽度和高度的 Box 对象的体积。这是 class 的一部分,因此 l,b,h
是私有成员:
long long CalculateVolume(){
return l*b*h;
}
这对于 l,b,h
的大值无法正常工作。就我而言 l = 1039, b = 3749, h = 8473
。结果是
-1355615565
我以为这是溢出,所以我试了
unsigned long long CalculateVolume(){
return l*b*h;
}
但结果是
18446744072353936051
最后,有效的方法是逐步将整数相乘:
long long CalculateVolume(){
long long result = l;
result *= b;
result *= h;
return result;
}
给出了 33004122803
的正确结果。我不明白为什么这个解决方案有效。你能解释一下这三种情况中每一种的幕后情况吗?谢谢!
如果变量 l
、b
和 h
是 long long
,那么两个代码段的行为将是相同的。
但是,如果变量是int
s,那么在第一个片段中
return l * b * h;
会导致溢出。到 long long
的转换只会在结果 返回 时发生,但为时已晚。
在此代码段中
long long result = l;
result *= b; // multiplying 'int' and 'long long' is like multiplying 2 'long long's
result *= h;
return result;
你只会乘以 long long
s,所以你不会溢出。
您可以让变量 long long
开始,或者在相乘之前转换变量。
我认为你的 3 variables:l、b 和 h 的类型是导致错误行为的原因,如果它们是整数值,它们的乘法也是整数。所以你必须在相乘之前将它们转换为 long long 或 unsigned long long。或者就像您在最后一段代码中所做的那样,您可以只转换其中一个,然后乘法将具有因子之间最大的类型(在这种情况下为 long long)