long long vs int乘法 [英] long long vs int multiplication

查看:697
本文介绍了long long vs int乘法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下代码段:

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

The output with MinGW GCC 3.4.5 is (-O0):

1
4
8
10000
-1486618624

第一个乘法在内部强制转换为int32(根据汇编程序输出).第二个乘法不强制转换.我不确定结果是否有所不同,是因为该程序在IA32上运行,还是因为它是在C标准中定义的.不过,我对是否在某处定义了确切的行为感兴趣(ISO/IEC 9899?),因为我想更好地理解为什么以及何时必须手动进行强制转换(在移植来自不同体系结构的程序时遇到了问题). /p>

The first multiplication is casted to an int32 internally (according to the assembler output). The second multiplication is not casted. I'm not sure if the results differ because the program was running on a IA32, or because it is defined somewhere in the C standard. Nevertheless I'm interested if this exact behavior is defined somewhere (ISO/IEC 9899?), because I like to better understand why and when I've to cast manually (I've problems porting a program from a different architecture).

推荐答案

C99标准确实指定了二进制运算符(例如*)不能对小于int的整数类型进行运算.在应用运算符之前,将这些类型的表达式提升为int.参见6.3.1.4第2段和整数提升"一词的多次出现.但这在某种程度上与编译器生成的汇编指令正交,后者在int上运行,因为即使允许编译器计算较短的结果,这也更快(因为该结果立即存储在L的l值中).简称).

The C99 standard does specify that binary operators such as * do not operate on integer types smaller than int. Expressions of these types are promoted to int before the operator is applied. See 6.3.1.4 paragraph 2 and the numerous occurrences of the words "integer promotion". But this is somewhat orthogonal to the assembly instructions generated by the compiler, which operate on ints because this is faster even when the compiler would be allowed to computed a shorter result (because the result is immediately stored in an l-value of a short type, for instance).

对于int64 f = d * e;,其中deint类型,根据相同的升级规则,将乘法作为int进行.从技术上讲,该溢出是未定义的行为,您在这里得到的结果是2补码,但是根据标准您可以得到任何结果.

Regarding int64 f = d * e; where d and e are of type int, the multiplication is done as an int in accordance with the same promotion rules. The overflow is technically undefined behavior, you are getting two-s-complement result here, but you could get anything according to the standard.

注意:升级规则在升级时区分带符号和无符号类型.规则是将较小的类型提升为int,除非int不能代表该类型的所有值,在这种情况下使用unsigned int.

Note: the promotion rules distinguish signed and unsigned types when promoting. The rule is to promote smaller types to int unless int cannot represent all values of the type, in which case unsigned int is used.

这篇关于long long vs int乘法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆