可能重复:
multiplication of large numbers, how to catch overflow
接近C,C ++和D等金属语言时,最有效的合理可移植方式(即不使用汇编程序,虽然你可以假设两个补码运算和环绕行为)来检测无符号的溢出乘法时是64位整数?
答案 0 :(得分:19)
您可以通过将无符号类型可表示的最大值除以其中一个被乘数来预先检测溢出;如果结果小于另一个被乘数,则将它们相乘会产生超出无符号类型范围的值。
例如,在C ++中(使用C ++ 0x精确宽度数字类型):
std::uint64_t left = 12;
std::uint64_t right = 42;
if (left != 0 && (std::numeric_limits<std::uint64_t>::max() / left) < right)
{
// multiplication would exceed range of unsigned
}
在C中,您可以使用uint64_t
作为类型,使用UINT64_MAX
作为最大值。或者,如果您只关心类型至少 64位宽而不一定正好 64位宽,则可以使用unsigned long long
和{{1} }。
答案 1 :(得分:3)
这个almost duplicate question有几个答案。 This answer应该使用C,C ++和其他类似语言:
if (b > 0 && a > 18446744073709551615 / b) {
// overflow handling
} else {
c = a * b;
}
或this answer执行乘法,然后将结果除以其中一个参数,看它是否等于另一个:
x = a * b;
if (a != 0 && x / a != b) {
// overflow handling
}
答案 2 :(得分:2)
可能有更有效的方法,但这是一种简单易用的方法:
// assume 'a' and 'b' are the operands to be multiplied
if( ( a != 0 ) && ( UINT64_MAX / a ) < b ) ) {
// overflow
}