0

私が次のことをした場合:

int c0 = CHAR_MAX; //8 bit
int c1 = CHAR_MAX; //8-bit
int i = c0*c1; //store in 32-bit variable
printf("%d\n", i); //prints 16129

8 ビットの数値を掛け合わせて 32 ビットの出力を生成することに問題がないことがわかります。

しかし、もしそうなら

int i0 = INT_MAX; //32-bit
int i1 = INT_MAX; //32 bit variable
long long int ll = i0*i1; //store in 64-bit variable
printf("%lld\n", ll); //prints 1..overflow!!

この場合、2 つの 32 ビット変数が乗算されてオーバーフローし、64 ビット変数に代入されました。

では、int を乗算するときにこのオーバーフローが発生し、char を乗算しないのはなぜでしょうか? 私のマシンのデフォルトのワードサイズに依存していますか? (32ビット)

4

3 に答える 3

3

2 番目のコード サンプルを次のように変更する必要があります。

int i0 = INT_MAX; //32-bit
int i1 = INT_MAX; //32 bit variable
long long ll = ((long long)i0)*i1; //compute and store in 64-bit variable
printf("%lld\n", ll);

つまり、整数 (少なくとも 1 つ) を乗算する前に 64 ビットにキャストします。intそうしないと、結果を変数に代入する前に一時的な型に格納しようとするため、オーバーフローが発生しlong longます。任意の式の結果は、最高の精度でそのメンバーの精度にキャストされます。

最初の例では、anintは s の乗算の結果を保持するのに十分な大きさであるため、charオーバーフローは発生しません。

llちなみに、数字の「1」と小文字の「l」を区別するのは非常に難しいため、変数に名前を付けることはお勧めしません。

于 2010-04-19T11:11:09.343 に答える
1

何が起こっているのかについてのあなたの説明には論理的な誤りがあります。

少なくとも Linux システムでは、CHAR_MAX確かに 8 ビットの数値ではありません。次のように、(多かれ少なかれ) 単純なプリプロセッサ定義です。

#  define SCHAR_MAX     127

/* Maximum value an `unsigned char' can hold.  (Minimum is 0.)  */
#  define UCHAR_MAX     255

/* Minimum and maximum values a `char' can hold.  */
#  ifdef __CHAR_UNSIGNED__
#   define CHAR_MIN     0
#   define CHAR_MAX     UCHAR_MAX
#  else
#   define CHAR_MIN     SCHAR_MIN
#   define CHAR_MAX     SCHAR_MAX
#  endif

したがって、符号付きchars を持つシステムでは、最後の 2 行が有効です。つまり、コードに CHAR_MAX を記述すると、コンパイラは型がint.

これは、乗算CHAR_MAX*CHAR_MAXint精度で行われることを意味します。

于 2010-04-19T11:26:47.107 に答える
0

タイプキャストの仕組み...


明示的な型キャストが指定されていない限り、式は関連する最高精度の変数/定数の精度に型キャストされます。

ピーターが指摘したように、式で明示的な型キャストを使用して、より高い精度を強制します。

注:「long long int」の部分がわかりませんでした。久しぶりに見たかも…;-)

  • long long intは本当に 64 ビットの int を宣言しますか??

Uはどのコンパイラを使用していますか??

于 2010-04-19T11:17:03.527 に答える