Считайте, что знак (+1
или же -1
) известен и существует код, который анализирует целое число без знака. Это целое число без знака может быть равно -numeric_limits<int64_t>::max()
, Как правильно сравнивать, не вызывая неопределенного поведения?
int8_t sign = /* +1 or -1 */;
uint64_t result = /* parse the remaining string as unsigned integer */;
if( result > uint64_t(numeric_limits<int64_t>::max()))
{
if(sign == 1) return false; // error: out of range for int64_t
// Is the below code correct or how to implement correctly its intent?
if(result == uint64_t(-numeric_limits<int64_t>::min()))
{
return true;
}
return false;
}
Как отмечает Холт, вы фактически предполагаете, что арифметика с дополнением 2-х. Поэтому вы можете заменить -min
от max+1
:
if(result == uint64_t(numeric_limits<int64_t>::max()) + 1)
Это позволяет избежать неопределенного поведения (переполнения целых чисел со знаком), которое возникает при отрицании минимального значения.
Это может быть хорошей идеей, чтобы убедиться, что ваша система действительно использует дополнение 2 (зависит от того, насколько строго вы хотите соответствовать стандарту C ++). Это может быть достигнуто путем сравнения -max
с min
:
if (numeric_limits<int64_t>::max() + numeric_limits<int64_t>::min() == 0)
{
// If not two's complement:
// Too large absolute value == error, regardless of sign
return false;
// on all sane (2's complement) systems this will be optimized out
}
Там нет возможностей для других отношений между min
а также max
; это объясняется Вот.
Других решений пока нет …