关于符号位扩展你又知道多少

来源:互联网 发布:c一维数组排序算法 编辑:程序博客网 时间:2024/05/29 14:07

转载请注明出处

http://blog.csdn.net/pony_maggie/article/details/37535577

作者:小马



先看两段代码, 一个是C,一个是java。

 

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. int _tmain(int argc, _TCHAR* argv[])  
  2. {  
  3.     char b = 0x83;  
  4.     short s1 = (short)b;  
  5.     short s2 = (short)(b&0xff);  
  6.   
  7.     printf("s1 = %d\n", s1);  
  8.     printf("s2 = %d\n", s2);  
  9.   
  10.   
  11.     return 0;  
  12. }  

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public static void main(String[] args)   
  2. {  
  3.         byte b = (byte)0x83;  
  4.         short s1 = (short)b;  
  5.         short s2 = (short)(b&0xff);  
  6.           
  7.         System.out.printf("s1 = %d\n", s1);  
  8.         System.out.printf("s2 = %d\n", s2);  
  9.   
  10. }  
运行结果其实是一样的:

s1 = -125

s2 = 131

 

用两种语言,是想说明它的通用性,表示这个特性跟语言本身无关。那么原因是什么呢?

 

首先,第二个结果才是我们期望的,这个应该都同意(至少大部分情况下都是这样)。其次如果变量b是正数(这里是负数,因为char表示有符号数,0x83最高位是1,表示负数),S1和S2的结果是相等的。


所以,问题的核心其实还是变量b的这个符号位。计算机里从低精度数向高精度数转换时,比如这里从char到short, 肯定会在前面扩展一些bit位,从而达到高精度数的长度。那么扩展时,是补0还是补1呢?这里有个原则就是,有符号数扩展符号位,也就是1,无符号数扩展0

 

再看看上面的代码,s1其实是0xff83, 是个负数,它表示的值就是-125(注意0xff83是补码表示,计算原值要换成原码)。而s2是0x0083, 因为它强制与上了0xff,其实就是与上了0x00ff。这样就把高字节转成了0x00,消除了符号位。

 

为了证明上面的理论,可以做一个实验,把代码改成这样:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. int _tmain(int argc, _TCHAR* argv[])  
  2. {  
  3.     char b = 0x83;  
  4.     short s1 = (short)b;  
  5.     short s2 = (short)(b&0xffff);  
  6.   
  7.     printf("s1 = %d\n", s1);  
  8.     printf("s2 = %d\n", s2);  
  9.   
  10.   
  11.     return 0;  
  12. }  
运行,结果是s1=s2=-125。这也支持了上面的理论分析。

 

趁热打铁,再看一个示例:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. int _tmain(int argc, _TCHAR* argv[])  
  2. {  
  3.     char a = 0xff;  
  4.     if (a == 0xff)  
  5.     {  
  6.         printf("equal\n");  
  7.     }  
  8.   
  9.     return 0;  
  10. }  
运行的结果是, “equal”并没有打印出来。你可能已经分析出原因了。字符a在和0xff比较时,被隐式的转换成int(因为0xff是整型),然后a做了符号位扩展,变为0xffffffff, 这个值和0x000000ff比较,当然是不等的。


我希望已经讲清楚了,欢迎拍砖。

0 0
原创粉丝点击