Search code examples
c++stlint64uint64numeric-limits

How to compare to numeric_limits<int64_t>::min()


Consider that the sign (+1 or -1) is known and there is a code that parses unsigned integer. That unsigned integer can be equal to -numeric_limits<int64_t>::max(). How to correctly compare without triggering undefined behavior?

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;
}

Solution

  • As noted by Holt, you're effectively assuming 2's complement arithmetic. Therefore, you can replace -min by max+1:

    if(result == uint64_t(numeric_limits<int64_t>::max()) + 1)
    

    This avoids the undefined behavior (signed integer overflow) that results when negating the minimal value.

    It might be a good idea to verify your system really uses 2's complement (depends on how strictly you want to comply with the C++ standard). This can be achieved by comparing -max with 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
    }
    

    There are no possibilities for other relations between min and max; this is explained here.