Most efficient portable overflow detection? [duplicate]

泄露秘密 提交于 2020-01-13 08:50:06

问题


In close to the metal languages like C, C++ and D, what's the most efficient reasonably portable way (i.e. w/o using assembler, though you may assume two's complement arithmetic and wrap-around behavior) to detect overflow of an unsigned 64-bit integer on multiplication?


回答1:


You can detect overflow in advance by dividing the maximum value representable by the unsigned type by one of the multiplicands; if the result is less than the other multiplicand, then multiplying them would result in a value exceeding the range of the unsigned type.

For example, in C++ (using the C++0x exact-width numeric types):

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
}

In C, you can use uint64_t for the type and UINT64_MAX for the maximum value. Or, if you only care that the type is at least 64 bits wide and not necessarily exactly 64 bits wide, you can use unsigned long long and ULLONG_MAX.




回答2:


There are a few answers in this almost duplicate question. This answer should work in C, C++, and other similar languages:

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

Or this answer which performs the multiplication and then divides the result by one of the arguments to see if it equals the other:

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



回答3:


There are probably more efficient methods but this is an easy and portable way to do it:

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


来源:https://stackoverflow.com/questions/3224621/most-efficient-portable-overflow-detection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!