最有效的便携式溢出检测?

可能重复:
乘数大,如何捕获溢出

接近C,C ++和D等金属语言,最有效的合理可移植方式(即使用汇编程序,虽然你可以假设两个补码运算和环绕行为)来检测无符号64位的溢出乘法上的整数?

您可以通过将无符号类型可表示的最大值除以其中一个被乘数来预先检测溢出; 如果结果小于另一个被乘数,则将它们相乘会产生超出无符号类型范围的值。

例如,在C ++中(使用C ++ 0x精确宽度数字类型):

std::uint64_t left = 12; std::uint64_t right = 42; if (left != 0 && (std::numeric_limits::max() / left) < right) { // multiplication would exceed range of unsigned } 

在C中,您可以使用uint64_t作为类型,使用UINT64_MAX作为最大值。 或者,如果您只关心该类型的宽度至少为 64位且不一定恰好为 64位宽,则可以使用unsigned long longULLONG_MAX

这个几乎重复的问题有几个答案。 这个答案应该适用于C,C ++和其他类似的语言:

 if (b > 0 && a > 18446744073709551615 / b) { // overflow handling } else { c = a * b; } 

或者这个执行乘法的答案然后将结果除以其中一个参数以查看它是否等于另一个:

 x = a * b; if (a != 0 && x / a != b) { // overflow handling } 

可能有更高效的方法,但这是一种简单易用的方法:

 // assume 'a' and 'b' are the operands to be multiplied if( ( a != 0 ) && ( UINT64_MAX / a ) < b ) ) { // overflow }