9

わかりました、これは奇妙な問題です:

  • 私はunsigned long long変数を使用しています(long同じ効果で変数を使用しました)
  • 64 ビット整数を格納できるようにする必要sizeofがあります ( 8 を返しますが、これで問題ありません)。

1<<63ただし、 のような値に移動して単純なビット演算を実行しようとすると、奇妙なことに、負の値を取得しているように見えます。なぜですか?

私のテストコード:

    unsigned long long c = 0;

    c |= 1l << 56; printf("c = %lld\n",c);
    c |= 1l << 63; printf("c = %lld\n",c);

出力:

c = 72057594037927936 
c = -9151314442816847872

補足:

  1. c = 1l<<63もちろん直接やっても同じです。
  2. すべてのテストは Mac OS X 10.6 で行われ、Apple の LLVM Compiler 3.0 を使用してコンパイルされました

助言がありますか?

4

2 に答える 2

22

指定子のd部分は、引数を符号付き整数として扱う必要があることを示しています。代わりにaを使用してください: .%lldprintfu%llu

マニュアルページから:

d、私

int 引数は、符号付き10 進数表記に変換されます。

o、u、x、X

unsigned int 引数は、 符号なし 8 進数 (o)、符号なし 10 進数 (u)、または符号なし16 進数 (x および X) 表記に変換されます。

于 2012-12-10T02:16:30.560 に答える
4

ここで実際に未定義のことをしていると思います。1l << 63 コンパイラは1l符号付きの型で表現し、63 ビットでシフトすると符号付きオーバーフローが発生するため ( C では未定義) 、式は C では未定義であると思います。私は専門家ではありませんが、あなたが望むようです1ull << 63

-Weverything実際、 clangを渡すと、元のコードはこれについて不平を言います。

foo.c:7:23: warning: signed shift result (0x8000000000000000) sets the sign bit of the
            shift expression's type ('long') and becomes negative [-Wshift-sign-overflow]
      c |= 1l << 63; printf("c = %lld\n",c);
           ~~ ^  ~~

編集:そして、はい、他の回答から正しいprintf形式が必要です。

于 2012-12-10T02:40:28.597 に答える