1

符号 (+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;
}
4

1 に答える 1

3

Holtが指摘したように、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
}

と の間の他の関係の可能性はありませminmax。これはここで説明されています。

于 2015-10-26T11:16:13.587 に答える