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

dsi*_*cha 8 c c++ integer d overflow

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

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

Jam*_*lis 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
}
Run Code Online (Sandbox Code Playgroud)

在C中,您可以使用uint64_t类型和UINT64_MAX最大值.或者,如果您只关心该类型至少为 64位宽而不一定 64位宽,则可以使用unsigned long longULLONG_MAX.


Mar*_*ers 3

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

if (b > 0 && a > 18446744073709551615 / b) {
     // overflow handling
} else {
    c = a * b;
}
Run Code Online (Sandbox Code Playgroud)

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

x = a * b;
if (a != 0 && x / a != b) {
    // overflow handling
}
Run Code Online (Sandbox Code Playgroud)

  • 我将使用 &lt;limits.h&gt; 宏 (c) 或 std::numeric_limits::max (C++) 指定的所用类型的最大值,而不是 18446744073709551615。 (5认同)