If either is long double the other is promoted to long double
If either is double the other is promoted to double
If either is float the other is promoted to float
If either is long long unsigned int the other is promoted to long long unsigned int
If either is long long int the other is promoted to long long int
If either is long unsigned int the other is promoted to long unsigned int
If either is long int the other is promoted to long int
If either is unsigned int the other is promoted to unsigned int
If either is int the other is promoted to int
Both operands are promoted to int
注意 . 最小操作大小为 int . 所以 short / char 在操作完成之前被提升为 int .
在所有表达式中, int 在执行操作之前被提升为 float . 操作的结果是 float .
int + float => float + float = float
int * float => float * float = float
float * int => float * float = float
int / float => float / float = float
float / int => float / float = float
int / int = int
int ^ float => <compiler error>
16
涉及 float 的算术运算结果为 float .
int + float = float
int * float = float
float * int = float
int / float = float
float / int = float
int / int = int
我的solution到了problem得到了WA(错误答案),然后我将 int 中的一个更改为 long long int 并且它给了AC(accept) . 以前,我试图做 long long int += int * int ,并在我纠正到 long long int += long long int * int 之后 . 谷歌搜索我想出来,
1.算术转换
类型转换的条件:
条件符合--->转换
任一操作数的类型为 long double . --->其他操作数转换为 long double 类型 .
9 回答
在C运算符(对于POD类型)中,始终对相同类型的对象执行操作 .
因此,如果它们不相同,则将提升以匹配另一个 .
操作结果的类型与操作数相同(转换后) .
注意 . 最小操作大小为
int
. 所以short
/char
在操作完成之前被提升为int
.在所有表达式中,
int
在执行操作之前被提升为float
. 操作的结果是float
.涉及
float
的算术运算结果为float
.有关详细解答 . 看看C标准的第5/9节是什么
由于其他答案没有谈到C 11中的规则,这里是一个 . 从C 11标准(草案n3337)§5/ 9:
有关经常更新的列表,请参阅here .
这个答案在很大程度上取决于@RafałDowgird的评论:
请记住,C标准具有非常重要的“假设”规则 . 请参见第1.8节:程序执行:
编译器不能将
int
的大小设置为8位,即使它是最快的,因为标准要求最小16位int
.因此,在理论计算机具有超快速8位操作的情况下,隐式升级到
int
算术可能很重要 . 但是,对于许多操作,您无法判断编译器是否实际以int
的精度执行了操作,然后转换为char
以存储在您的变量中,或者操作是否始终在char中完成 .例如,考虑
unsigned char = unsigned char + unsigned char + unsigned char
,其中加法会溢出(让我们假设每个值为200) . 如果你升级到int
,你将获得600,然后将隐式向下转换为unsigned char
,这将包装模256,从而给出88的最终结果 . 如果你没有这样的促销,你必须在前两个添加,将把问题从200 + 200 + 200
减少到144 + 200
,即344,减少到88.换句话说,程序不知道差异,因此编译器可以自由地忽略执行中间操作的任务int
如果操作数的排名低于int
.这通常是加法,减法和乘法 . 对于除法或模数,一般情况并非如此 .
如果排除无符号类型,则存在有序层次结构:signed char,short,int,long,long long,float,double,long double . 首先,在上面的int之前的所有内容都将转换为int . 然后,在二进制操作中,较低等级的类型将被转换为较高的,并且结果将是较高的类型 . (您将注意到,从层次结构中,只要涉及浮点和整数类型,整数类型将转换为浮点类型 . )
无符号使事情变得复杂:它扰乱了排名,并且部分排名变为实现定义 . 因此,最好不要在同一个表达式中混合使用signed和unsigned . (大多数C专家似乎都避免使用无符号,除非涉及按位操作 . 至少,Stroustrup建议使用 . )
我的solution到了problem得到了WA(错误答案),然后我将
int
中的一个更改为long long int
并且它给了AC(accept) . 以前,我试图做long long int += int * int
,并在我纠正到long long int += long long int * int
之后 . 谷歌搜索我想出来,1.算术转换
类型转换的条件:
条件符合--->转换
任一操作数的类型为 long double . --->其他操作数转换为 long double 类型 .
未满足前置条件且任一操作数的类型为 double . --->其他操作数转换为 double 类型 .
未满足前置条件且任一操作数的类型为 float . --->其他操作数转换为 float 类型 .
未满足前置条件(没有任何操作数是浮点类型) . --->对操作数执行整体促销,如下所示:
如果任一操作数的类型为 unsigned long ,则另一个操作数将转换为 unsigned long 类型 .
如果未满足先前条件,并且任一操作数的类型为 long 且另一个类型为 unsigned int ,则两个操作数都将转换为 unsigned long 类型 .
如果不满足前两个条件,并且任一操作数的类型为 long ,则其他操作数将转换为 long 类型 .
如果不满足前面的三个条件,并且任一操作数的类型为 unsigned int ,则另一个操作数将转换为 unsigned int 类型 .
如果不满足上述条件,则两个操作数都将转换为 int 类型 .
2 . 整数转换规则
在对它们执行操作时,将提升小于int的整数类型 . 如果原始类型的所有值都可以表示为int,则较小类型的值将转换为int;否则,它将转换为unsigned int . 整数促销作为通常算术转换的一部分应用于某些参数表达式;一元, - 和〜运算符的操作数;移位运算符和操作数 .
整数转换排名:
没有两个有符号整数类型具有相同的等级,即使它们具有相同的表示 .
有符号整数类型的等级应大于精度较低的任何有符号整数类型的等级 .
long long int
的等级应大于long int
的等级,该等级应大于int
的等级,该等级应大于short int
的等级,该等级应大于signed char
的等级 .任何无符号整数类型的等级应等于相应的有符号整数类型的等级(如果有) .
任何标准整数类型的等级应大于具有相同宽度的任何扩展整数类型的等级 .
char
的等级应等于signed char
和unsigned char
的等级 .任何扩展有符号整数类型相对于具有相同精度的另一个扩展有符号整数类型的等级是实现定义的,但仍然受制于确定整数转换等级的其他规则 .
对于所有整数类型T1,T2和T3,如果T1具有比T2更大的秩并且T2具有比T3更大的秩,则T1具有比T3更大的秩 .
通常的算术转换:
如果两个操作数具有相同的类型,则不需要进一步转换 .
如果两个操作数具有相同的整数类型(有符号或无符号),则具有较小整数转换等级类型的操作数将转换为具有较高等级的操作数的类型 .
如果具有无符号整数类型的操作数的秩大于或等于另一个操作数的类型的等级,则带有符号整数类型的操作数将转换为具有无符号整数类型的操作数的类型 .
如果带有符号整数类型的操作数的类型可以表示具有无符号整数类型的操作数类型的所有值,则具有无符号整数类型的操作数将转换为带有符号整数类型的操作数的类型 .
否则,两个操作数都转换为无符号整数类型,对应于带有符号整数类型的操作数类型 . 特定操作可以添加或修改通常的算术运算的语义 .
整个第4章讨论了转换,但我认为你应该最感兴趣的是:
4.5 Integral promotions [conv.prom]
如果int可以表示源类型的所有值,则可以将char,signed char,unsigned char,short int或unsigned short int类型的rvalue转换为int类型的rvalue . 其他-
明智的是,源rvalue可以转换为unsigned int类型的右值 .
类型为wchar_t(3.9.1)或枚举类型(7.2)的右值可以转换为第一个的右值
可以表示其基础类型的所有值的以下类型:int,unsigned int,
长或无符号长 .
如果int可以表示all,则可以将积分位域(9.6)的rvalue转换为int类型的rvalue
位域的值;否则,如果unsigned int可以代表它,它可以转换为unsigned int
重新发现位域的所有值 . 如果位字段较大,则不适用整数提升 . 如果
bit-field具有枚举类型,它被视为该类型的任何其他值以用于促销目的 .
bool类型的rvalue可以转换为int类型的rvalue,false变为零和true
成为一体 .
这些转化称为整体促销 .
4.6 Floating point promotion [conv.fpprom]
float类型的右值可以转换为double类型的右值 . 该值保持不变 .
此转换称为浮点提升 .
因此,所有涉及浮点数的转换 - 结果都是浮点数 .
只涉及两个int - 结果是int:int / int = int
当两个部分属于同一类型时,表达式的类型将被转换为两者中最大的 . 这里的问题是要了解哪一个比另一个大(它与字节大小没有任何关系) .
在涉及实数和整数的表达式中,整数将被提升为实数 . 例如,在int float中,表达式的类型为float .
另一个区别与该类型的能力有关 . 例如,涉及int和long int的表达式将生成long int类型 .
警告!
转换从左到右进行 .
试试这个: