1

INT_MAX および INT_MIN 定数を使用すると、-2147483648 ... 2147483647 になります。

しかし、この関数を使用して int の最大値と最小値を計算しようとすると:

static int computeInt(void)
{
    int myInt = 0;
    int min = 0;
    int max = 32;

    for (int i = min; i < max; i++)
    {
        myInt = myInt + pow(2, i);
    }

    myInt = myInt / 2;

    return myInt;
}

同じ数字が出ません。何が起こるかについての技術的なことは、myInt がオーバーフローすることだと思います。

ありがとう!

4

4 に答える 4

5

はい、int の範囲が -2^31 から 2^31 - 1 であり、0 から 31 までの 2 のべき乗の合計を計算しようとするため、オーバーフローが発生します。最終的な値は次の結果です:(2^0 + 2^1 + 2^3 + ... + 2^31) / 2これは明らかに2^31 - 1 より大きい

于 2013-03-06T11:30:10.103 に答える
2

整数が結果を超えるとすぐにINT_MAX結果が定義されないため (単純にクラッシュする可能性があります)、この方法で算術演算を使用して最大符号付き整数を確実に検出することはできません。

ただし、符号なし整数の最大値を計算することはできます。これは、0 に戻ることUINT_MAX + 1が保証されているため0です。同様に、unsigned int a = -1に等しくなりUINT_MAXます。

signedintとは同じ量のストレージとアラインメントを使用することが保証されているため、計算された を 2 でunsigned int除算して を得ることができます。したがって:UINT_MAXINT_MAX

unsigned int maxint = -1;
maxint /= 2;
于 2013-03-06T12:17:52.373 に答える
2

あなたの仮定は正しいです。あなたintはそれに追加し続けるので、あなたのオーバーフロー。最大 int が単純に 2^31-1 またはpow(2,31)-1.

ループを使用すると、次のことができます。

for (int i = min; i < max; i++) {
    myInt = myInt * 2;
}
myInt = myInt - 1;

(このループでも一時的なオーバーフローが発生することに注意してください。最後の反復の後はmyIntになりますが-2147483648、1 を減算すると になります2147483647)

于 2013-03-06T11:26:35.327 に答える
1

前の回答とコメントで述べたように、オーバーフローがあります ( を想定してsizeof(int) = 4いる場合でも。これらの定数を「手動で」計算したい場合は、次のようにするだけです。

int myInt = (((unsigned int)(-1)) >> 1);
int myIntMin = -myInt - 1;

これは、符号付き整数が 2 の補数論理を使用して表され、整数表現にパディング ビットがないことを前提としているため、完全にアーキテクチャに依存しているわけではありません。しかし、多くの場合、これで問題なく動作するはずです (x86 PC でテスト済み)。

于 2013-03-06T11:42:38.137 に答える