设为首页 加入收藏

TOP

14.3.5 编译器如何处理类型转换
2013-10-12 06:53:22 来源: 作者: 【 】 浏览:90
Tags:14.3.5 编译器 如何 处理 类型 转换

14.3.5  编译器如何处理类型转换

以上几节介绍了在哪些情况下会发生类型转换,并且明确了每种情况下会把什么类型转成什么类型,本节介绍编译器如何处理任意两种类型之间的转换。现在要把一个M位的类型(值为X)转换成一个N位的类型,所有可能的情况如表14.3所示。

表14.3  如何做类型转换

待转换的类型< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

M > N的情况

M == N的情况

M < N
的情况

signed integer to signed integer

如果X在目标类型的取值范围内则值不变,否则Implementation-defined

值不变

值不变

unsigned integer to signed integer

如果X在目标类型的取值范围内则值不变,否则Implementation-defined

如果X在目标类型的取值范围内则值不变,否则Implementation-defined

值不变

signed integer to unsigned integer

X % 2N

X % 2N

X % 2N

unsigned integer to unsigned integer

X % 2N

值不变

值不变

floating-point to signed or unsigned integer

Truncate toward Zero,如果X的整数部分超出目标类型的取值范围则Undefined

signed or unsigned integer to floating- point

如果X在目标类型的取值范围内则值不变,但有可能损失精度;如果X超出目标类型的取值范围则Undefined

floating-point to floating-point

如果X在目标类型的取值范围内则值不变,但有可能损失精度;如果X超出目标类型的取值范围则Undefined

值不变

值不变

注意表14.3中的"X % 2N",我想表达的意思是"把X加上或者减去2N的整数倍,使结果落入[0, 2N-1]的范围内",当X是负数时运算结果也是正数,即运算结果和除数同号而不是和被除数同号,这不同于C语言中%运算的定义。写程序时不要故意用表14.3中的规则,尤其不要触碰Implementation-defined和Undefined的情况,但程序出错时可以借助表14.3分析错误原因。

下面举几个例子说明表14.3的用法。比如把double型转换成short型,对应表中的"floating-point to signed or unsigned integer",如果原值在(-32769.0, 32768.0)之间,则截掉小数部分得到转换结果,否则产生溢出,结果是Undefined,例如对于short s = 32768.4;这个语句gcc会报警。

比如把int型转换成unsigned short型,对应表中的"signed integer to unsigned integer"。如果原值是正的,则把它除以216取模,其实就是取它的低16位;如果原值是负的,则加上216的整数倍,使结果落在[0, 65535]之间。

比如把int类型转换成short类型,对应表中的"signed integer to signed integer"。如果原值在[-32768, 32767]之间则值不变,否则产生溢出,结果是Implementation-defined,例如对于short s = -32769;这个语句gcc会报警。

最后一个例子,把short型转换成int型,对应表中的"signed integer to signed integer",转换之后应该值不变。那怎么维持值不变呢?是不是在高位补16个0就行了呢?如果原值是-1,用十六进制数表示就是ffff,要转成int型的-1需要变成ffffffff,因此需要在高位补16个1而不是16个0。换句话说,要维持值不变,在高位补1还是补0取决于原来的符号位,这称为符号扩展(Sign Extension)。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇6.3 for语句 下一篇14.3.3 由赋值产生的类型转换

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: