ISO/IEC 9899:2011 条款6.3.1——算术操作数
6.3.1 算术操作数
6.3.1.1 布尔、字符以及整数
1、每个整数类型具有一个整数转换等级,如下定义:
——两个带符号的整数类型都不应该具有相同等级,即使它们具有相同的表示。
——一个带符号整数类型的等级应该比任一具有更低精度的带符号整数类型的等级要高。
——long long int的等级应该比long int的等级要高,而long int等级要比int等级要高,int要比short int等级要高,而short int要比signed char等级要高。
——任一无符号整数类型的等级应该等于相应的带符号整数类型,如果存在的话。
——任一标准整数类型的等级应该大于任一具有相同宽度的扩展整数类型的等级。
——char的等级应该等于signed char与unsigned char的等级。
——_Bool的等级应该小于所有其它标准整数类型的等级。
——任一枚举类型的等级应该等于相兼容整数类型的等级(见6.7.2.2)。
——任一扩展带符号整数类型相对于具有相同精度的另一个扩展带符号整数类型的等级是由实现定义的,但仍然遵从判定整数转换等级的其它规则。
——对于所有整数类型T1、T2和T3,如果T1具有比T2更高等级,且T2具有比T3更高的等级,那么T1比T3更高等级。
2、以下规则可以被用于int或unsigned int可以被使用的一个表达式中:
——具有一个整数类型的一个对象或表达式(除了int或unsigned int之外),其整数转换等级小于等于int与unsigned int的等级。
——类型_Bool、int、signed int或unsigned int的一个位域。
如果一个int可以表示原始类型的所有值(对于一个位域,由宽度所限定),那么该值被转换为一个int;否则,它被转换为一个unsigned int。这些被称为整数晋升。[注:整数晋升仅应用于:作为通常的算术转换的一部分,到某些实参表达式,到单目操作符+、-和~的操作数,以及移位操作符的两个操作数,通过它们相关的子条款指定。]所有其它类型不会被整数晋升所改变。
3、整数晋升保留了值,包括符号。正如之前所讨论的,一个“平凡的”char是否被看作为带符号还是无符号是实现定义的。
6.3.1.2 布尔类型
1、当任一标量值被转换为_Bool时,结果为0,如果该值与0比较相等;否则,结果为1。[注:非数NaN与0比较不为0,从而被转换为1。]
6.3.1.3 带符号与无符号整数
1、当具有整数类型的一个值被转换为另一个不为_Bool的整数类型时,如果该值可以用新的类型表示,那么该值不被改变。
2、否则,如果新的类型是无符号的,那么该值通过重复地加或减能在新的类型中可被表示的最大值加1,直到该值在新类型的范围内。[注:此规则描述了数学值上的算术计算,而不是一个给定类型的表达式的值]。[译者注:比如以下代码:
unsigned short a = 258; unsigned char b = (unsigned char)a; // b == 258 - 256 = 2
上述代码中,a为无符号短整型,它被转换为无符号char类型时通过减一次能用unsigned char所表示的最大值(255)加1来得到类型转换后的值,并存在b变量中。
]
3、否则,新的类型是带符号的并且该值不能用它来表示;结果可以是实现定义的,也可以引发实现定义的信号。
6.3.1.4 实浮点数与整数
1、当实浮点类型的一个有限值被转为除_Bool以外的一个整数类型时,尾数部分被丢弃(即,该值向零截断)。如果整数部分的值不能用整数类型来表示,那么行为是未定义的。[注:当整数类型的一个值被转为无符号类型时所执行的求余操作,当实浮点类型的一个值被转为无符号类型时不需要被执行。从而,可转换的实浮点值的范围是(-1, U类型_MAX + 1)。]
2、当一个整数类型的值被转换为一个实浮点类型时,如果正被转换的值可以完全用该新类型来表示,那么它的值不会被改变。如果正在被转换的值在可被表示的值的范围内,但不能被完全表示,那么结果要么为最近最大的,要么为最近最小可表示的值,此选择为实现定义的行为。如果正在被转换的值在可被表示的范围之外,那么行为是未定义的。某些隐式转换可以在更大范围和精度内被表示,比起由新类型所能所需要的范围和精度(见6.3.1.8和6.8.6.4)。
6.3.1.5 实浮点类型
1、当实浮点数类型的一个值被转为一个实浮点类型时,如果正被转换的值可以完全用该新类型来表示,那么该值是不改变的。如果正被转换的值在能被表示的值的范围内,但不能完全被表示,那么结果要么为最近更大,要么为最近更小的值,此选择是一个实现定义的行为。如果正被转换的值在能被表示的范围外,那么该行为是未定义的。某些隐式转换的结果可以用更大范围和精度来表示,比起用新的类型所要求的范围和精度(见6.3.1.8和6.8.6.4)。
6.3.1.6 复数类型
1、当复数类型的一个值被转换为另一个复数类型,实数与虚数部分都遵循相应的实数类型的转换规则。
6.3.1.7 实数与复数
1、当一个实数类型的值被转换为一个复数类型时,该复数结果值的实数部分由相应于复数结果值的实数类型决定,并且虚数类型部分结果值是一个正零或一个无符号的零。
2、当一个复数类型的值被转换为一个实数类型时,复数值的虚数部分被丢弃,并且实数部分的值根据相应实数类型的转换规则进行转换。
6.3.1.8 通常的算术转换
1、许多期待算术类型操作数的操作符引发转换并以一种类似的方式产生结果类型。目的是为了确定操作数与结果的公共实数类型。对于指定的操作数,每个操组数被转换到一个类型,其相应的实数类型是公共实数类型,而不改变类型域。除非显式地阐明,否则公共的实数类型也是结果相应的结果类型,该结果的类型域为操作数的类型域,如果它们都相同的话,否则为复数。该模式被称为通常的算术转换:
首先,其中一个操作数的相应实数类型为long double,而另一个操作数被转换为一个类型,其相应的实数类型为long double,而不改变类型域。
否则,如果其中一个操作数的相应实数类型是double,另一个操作数被转换为一个类型,其相应的实数类型为double,而不改变类型域。
否则,如果其中一个操作数的相应实数类型为float,而另一个操作数被转换为一个类型,其相应的实数类型是float,而不改变类型域。[注:比如,double _Complex与一个float的加法使得float操作数到double的转换变为有所必要(并产生一个double _Complex结果)。]
否则,对两个操作数都执行整数晋升。然后对晋升的操作数应用以下规则:
如果两个操作数都具有相同类型,那么不需要进一步的转换。
否则,如果两个操作数都具有带符号类型或无符号类型,那么具有更小整数转换等级类型的操作数被转换为具有更大整数转换等级的操作数类型。
否则,如果具有无符号整数类型的操作数所具有的等级大于等于另一个操作数类型的等级,那么具有带符号整数类型的操作数被转换为具有无符号整数类型的操作数类型。
否则,如果具有带符号整数类型的操作数类型可以表示具有无符号整数类型的操作数类型的所有的值,那么无符号整数类型的操作数被转换为带有带符号整数类型的操作数类型。
否则,两个操作数都被转换为相应于具有带符号整数类型的操作数类型的无符号整数类型。
2、浮点操作数的值与浮点表达式结果的值可以用更大范围和精度来表示,比起该类型所需要的范围和精度;该类型从而不被改变。[注:但仍然要求投射与赋值操作符移除额外的范围和精度。]