Самое эффективное портативное водосливное обнаружение? [дубликат]

8
задан dbush 3 August 2019 в 14:38
поделиться

3 ответа

Вы можете заранее обнаружить переполнение, разделив максимальное значение, представляемое беззнаковым типом, на одно из множителей; если результат меньше другого множителя, то умножение их приведет к значению, превышающему диапазон беззнакового типа.

Например, в 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 и ULLONG_MAX.

19
ответ дан 5 December 2019 в 06:52
поделиться

В этом почти дублируемом вопросе есть несколько ответов. Этот ответ должен работать на 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
}
3
ответ дан 5 December 2019 в 06:52
поделиться

Вероятно, есть более эффективные методы, но это простой и портативный способ сделать это:

// assume 'a' and 'b' are the operands to be multiplied
if( ( a != 0 ) && ( UINT64_MAX / a ) < b ) ) {
  // overflow
}
2
ответ дан 5 December 2019 в 06:52
поделиться