long long vs int multiplication

给出以下代码段:

#include <stdio.h>

typedef signed long long int64;
typedef signed int int32;
typedef signed char int8;

int main()
{
    printf("%i\n", sizeof(int8));
    printf("%i\n", sizeof(int32));
    printf("%i\n", sizeof(int64));

    int8 a = 100;
    int8 b = 100;
    int32 c = a * b;
    printf("%i\n", c);

    int32 d = 1000000000;
    int32 e = 1000000000;
    int64 f = d * e;
    printf("%I64d\n", f);
}

MinGW GCC 3.4.5的输出为(-O0):

1
4
8
10000
-1486618624

第一个乘法在内部转换为int32(根据汇编器输出).第二次乘法不是铸造的.我不确定结果是否不同,因为程序在IA32上运行,或者因为它是在C标准的某处定义的.不过我感兴趣的是这个确切的行为是在某个地方定义的(ISO / IEC 9899?),因为我想更好地理解为什么以及什么时候我要手动编译(我有问题从不同的架构移植程序).

最佳答案
C99标准确实指定诸如*之类的二元运算符不对小于int的整数类型进行操作.在应用运算符之前,这些类型的表达式将提升为int.见6.3.1.4第2段和多次出现的“整数提升”.但这与编译器生成的汇编指令有些正交,后者在int上运行,因为即使允许编译器计算更短的结果,这也会更快(因为结果立即存储在short类型的l值中) , 例如).

关于int64 f = d * e;其中d和e的类型为int,乘法按照相同的促销规则以int形式完成.溢出在技术上是未定义的行为,你在这里获得了二进制补码结果,但你可以根据标准得到任何东西.

注意:促销规则区分已签名和未签名类型.规则是将较小的类型提升为int,除非int不能表示该类型的所有值,在这种情况下使用unsigned int.

转载注明原文:long long vs int multiplication - 代码日志