编译器如何处理类型转换

在两种类型之间做转换,转换结果将取决于两种类型的精度:

1. 精度是N的有符号整数类型应该用N个Bit表示,取值范围至少应该覆盖(-2N-1, 2N-1)。例如signed char型用8个Bit表示,表示的取值范围是[-128, 127],也可以说是覆盖了(-128, 128),所以这种类型的精度是8。

2. 精度是N的无符号整数类型应该用N个Bit表示,取值范围是[0, 2N-1]。

3. 精度是N的浮点数类型的取值范围至少应该覆盖(-2N-1, 2N-1)的整数值。

现在要把一个精度是M的类型(值为X)转换成一个精度是N的类型,所有可能的情况如下表所示:

待转换的类型

N < M的情况

N == M的情况

N > M的情况

signed integer to signed integer

discard m.s. M-N bits (can overflow)

same value

same value

unsigned integer to signed integer

if (X < 2N-1) same value else impl.-def.(can overflow)

if (X < 2N-1) same value else impl.-def.(can overflow)

same value

floating-point to signed integer

if (|X| < 2N-1) trunc(X) else imple.-def. (can overflow)

if (|X| < 2N-1) trunc(X) else imple.-def. (can overflow)

if (|X| < 2N-1) trunc(X) else imple.-def. (can overflow)

signed integer to unsigned integer

if (0 <= X) X % 2N else impl.-def.

if (0 <= X) same value else X + 2N

if (0 <= X) same value else X + 2N

unsigned integer to unsigned integer

X % 2N

same value

same value

floating-point to unsigned integer

if (0 <= X < 2N) trunc(X) else imple.-def. (can overflow)

if (0 <= X < 2N) trunc(X) else imple.-def. (can overflow)

if (0 <= X < 2N) trunc(X) else imple.-def. (can overflow)

signed integer to floating-point

keep sign, keep m.s.N-1 bits

same value

same value

unsigned integer to floating-point

+ sign, keep m.s. N-1 bits

+ sign, keep m.s. N-1 bits

same value

floating-point to floating point

keep m.s. N-1 bits (can overflow)

same value

same value

 

上表中的一些缩写说明如下:

impl.-def.表示Implementation-defined;

m.s. bit表示MostSignificant Bit;

trunc(X)表示取X的整数部分,即Truncate Toward Zero;

X % Y就是取模

用法:

float型转short型,对应表中的floating-point to signed integer一行,可以看到,不管两种类型的精度如何,处理方式是一样的,如果float类型的值在(-32768.0, 32768.0)之间,则截掉小数部分就可以了,如果float类型的值超出了这个范围,则转换结果是未明确定义的,有可能会产生溢出,例如对于short s =32768.4。 

把int类型转换成unsigned short类型,对应表中的unsigned integer to unsigned integer一行,如果int类型的值是正的,则把它除以216取模,其实就是取它的低16位,如果int类型的值是负的,则转换结果是未明确定义的。

把int类型转换成short类型,对应表中的第一行signed integer to signed integer,把int类型值的高16位丢掉(这里的m.s.包括符号位在内,上表中另外几处提到的m.s.应该是不算符号位在内),只留低16位,这种情况也有可能溢出,例如对于short s = -32769。

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

转载于:https://www.cnblogs.com/xiaojianliu/articles/8732772.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值