3 回答
TA贡献1806条经验 获得超5个赞
这在§5/ 9中明确概述:
许多期望算术或枚举类型的操作数的二元运算符会以类似的方式引起转换并产生结果类型。目的是产生一个通用类型,它也是结果的类型。这种模式称为通常的算术转换,定义如下:
如果任一操作数是类型
long double
,则另一个操作数应转换为long double
。否则,如果任一操作数是
double
,则另一个操作数应转换为double
。否则,如果任一操作数是
float
,则另一个操作数应转换为float
。否则,应对两个操作数执行整体促销。
然后,如果任一操作数是
unsigned long
另一个应转换为unsigned long
。否则,如果一个操作数是a
long int
和另一个unsigned int
,那么如果along int
可以表示a的所有值unsigned int
,unsigned int
则应转换为along int
; 否则两个操作数都应转换为unsigned long int
。否则,如果任一操作数是
long
,则另一个操作数应转换为long
。否则,如果任一操作数是
unsigned
,则另一个操作数应转换为unsigned
。[ 注意:否则,唯一剩下的情况是两个操作数都是
int
]
在两个场景中,结果operator+
都是unsigned
。因此,第二种情况是有效的:
int result = static_cast<int>(us + static_cast<unsigned>(neg));
因为在这种情况下,值us + neg
不能表示int
,值result
是实现定义的 - §4.7/ 3:
如果目标类型已签名,则如果可以在目标类型(和位字段宽度)中表示该值,则该值不会更改; 否则,该值是实现定义的。
TA贡献2051条经验 获得超10个赞
在C标准化之前,编译器之间存在差异 - 一些遵循“保值”规则,另一些遵循“签署保留”规则。保留符号意味着如果任一操作数是无符号的,则结果是无符号的。这很简单,但有时会给出相当惊人的结果(特别是当负数转换为无符号时)。
C对更复杂的“保值”规则进行了标准化。在保值规则下,促销可以/确实取决于类型的实际范围,因此您可以在不同的编译器上获得不同的结果。例如,在大多数MS-DOS编译器上,它们int
的大小short
和long
它们的大小相同。在许多当前系统int
上,它们的大小与之相同long
,并且short
两者都不同。使用保值规则,这些可以导致促销类型在两者之间不同。
值保留规则的基本思想是,如果可以表示较小类型的所有值,它将提升为更大的签名类型。例如,16位unsigned short
可以提升为32位signed int
,因为每个可能的值unsigned short
都可以表示为a signed int
。当且仅当需要保留较小类型的值时,类型将被提升为无符号类型(例如,如果unsigned short
和signed int
都是16位,则a signed int
不能代表所有可能的值unsigned short
,因此unsigned short
将被提升为unsigned int
)。
当您按原样分配结果时,无论如何都会将结果转换为目标类型,因此大多数情况都会产生相对较小的差异 - 至少在大多数情况下,它只会将位复制到结果中,并且由您来决定是将其解释为已签名还是未签名。
当你没有分配比较结果时,事情会变得非常难看。例如:
unsigned int a = 5;signed int b = -5;if (a > b) printf("Of course");else printf("What!");
在符号保留规则下,b
将被提升为无符号,并且在此过程中变得相等UINT_MAX - 4
,所以“什么!” if
将采取的腿。使用保值规则,您可以设法产生一些奇怪的结果,但是1)主要在类似DOS的系统中,int
其大小short
与2 相同,并且2)无论如何通常都难以做到。
TA贡献1880条经验 获得超4个赞
它会选择你输入结果的任何类型,或者至少cout在输出过程中尊重那种类型。
我不记得肯定,但我认为C ++编译器为两者生成相同的算术代码,它只是比较和输出关心符号。
- 3 回答
- 0 关注
- 375 浏览
添加回答
举报