4

以下のコードでは、(32 ビット)0xffffffffに 2を掛けて(64 ビット)unsigned intに格納しています。unsigned long longである実際の出力が得られないのはなぜですか8589934588。代わりに私は得る4294967294。前もって感謝します。出力: i=4 のサイズ J=8 のサイズ 2xi=4294967292

/* Code starts here */
#include <stdio.h>
#include <stdlib.h>

int main (void) 
{
    unsigned int i=4294967294;
    unsigned long long j=i*2;
    printf("Sizeof i=%d\n", sizeof(i));
    printf("Sizeof J=%d\n", sizeof(j));
    printf("2xi=%llu\n", j);

    return 0;
}
4

3 に答える 3

5

これi*2は整数乗算だからです。に格納しているにもかかわらず、long long整数演算を行っているため、オーバーフローが発生します。

long long次のコードは、乗算するように昇格すると機能します

#include <stdio.h>
#include <stdlib.h>
int main (void)
{
  unsigned int i=4294967294;
  unsigned long long j=((unsigned long long)i)*2;
  printf("Sizeof i=%d\n", sizeof(i));
  printf("Sizeof J=%d\n", sizeof(j));
  printf("2xi=%llu\n", j);

  return 0;
}

結果:

bash-4.1$ gcc long.c
bash-4.1$ ./a.out
Sizeof i=4
Sizeof J=8
2xi=8589934588
于 2013-07-31T20:05:07.503 に答える
3

i*2に割り当てられているという事実については何も知りませんunsigned long long-iは でありunsigned int2は でありint、型を使用して乗算が実行されunsigned int、得られた結果が得られます。

乗算のために昇格するリテラルを作成2するか、同じ効果を持つ乗算の前にキャストすることで、問題を解決できます。unsigned long longiunsigned long longiunsigned long long

unsigned long long j=i*2ULL;
/* or */
unsigned long long j=((unsigned long long)i)*2;

一般に、覚えておいてください: C では、割り当て/初期化のターゲットは、その右側の式の計算方法に影響しません。関連する型は、オペランドの型によってのみ決定されます。

于 2013-07-31T20:05:40.423 に答える
2

iis はunsigned intand2ですand は操作intに昇格するので、unsigned intラップアラウンドします。1 つの解決策は、次のようにキャストiすることunsigned long longです。

unsigned long long j = ((unsigned long long)i)*2 ;

ドラフト C11 標準の関連セクションは次の6.2.5/9とおりです。

結果の符号なし整数型で表現できない結果は、結果の型で表現できる最大値よりも 1 大きい数値を法として減らされるため、符号なしオペランドを含む計算はオーバーフローすることはありません。

于 2013-07-31T20:10:19.927 に答える