在C部分2中将char和int相乘

时间:2010-04-19 11:08:56

标签: c overflow multiplying

如果我执行以下操作:

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!!

在这种情况下,两个32位变量相乘,溢出,然后分配给64位变量。

那么为什么在增加整数而不是字符时会发生这种溢出?它取决于我的机器的默认字大小吗? (32位)

3 个答案:

答案 0 :(得分:3)

您应该更改第二个代码示例,例如

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);

即,在乘以它们之前将(至少一个)整数转换为64位。否则发生溢出是因为在将结果分配给int变量之前,尝试将结果存储在long long类型的临时表中。任何表达式的结果都以最高精度投射到其成员的精度。

在第一个示例中,int足以保存乘以char s的结果,因此没有溢出。

作为旁注,建议不要命名变量ll,因为很难区分数字'1'和小写字母'l'。

答案 1 :(得分: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

因此,对于带有签名char的系统,最后两行有效,这意味着当您在代码中编写CHAR_MAX时,编译器会看到一个类型为{{1}的平面127 }。

这意味着乘法int * CHAR_MAXCHAR_MAX精度发生。

答案 2 :(得分:0)

Typecast如何运作......


除非指定了明确的类型转换,否则任何表达式都会被转换为所涉及的最高精度变量/常量的精度。

  

正如彼得指出的那样,在表达式中使用明确的类型转换来强制更高的精确度。

注意:我没有得到“long long int”部分。也许这是很长时间,因为我看到了......; - )

  
      
  • long long int 是否真的声明了64位int?
  •   

哪个编译器使用??