• 关于符号扩展多少你自己知道


    转载请注明出处

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

    作者:小马



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

    int _tmain(int argc, _TCHAR* argv[])
    {
    	char b = 0x83;
    	short s1 = (short)b;
    	short s2 = (short)(b&0xff);
    
    	printf("s1 = %d
    ", s1);
    	printf("s2 = %d
    ", s2);
    
    
    	return 0;
    }

    public static void main(String[] args) 
    {
    		byte b = (byte)0x83;
    		short s1 = (short)b;
    		short s2 = (short)(b&0xff);
    		
    		System.out.printf("s1 = %d
    ", s1);
    		System.out.printf("s2 = %d
    ", s2);
    
    }
    执行结果事实上是一样的:

    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,消除了符号位。

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

    int _tmain(int argc, _TCHAR* argv[])
    {
    	char b = 0x83;
    	short s1 = (short)b;
    	short s2 = (short)(b&0xffff);
    
    	printf("s1 = %d
    ", s1);
    	printf("s2 = %d
    ", s2);
    
    
    	return 0;
    }
    执行,结果是s1=s2=-125。这也支持了上面的理论分析。

    趁热打铁。再看一个演示样例:

    int _tmain(int argc, _TCHAR* argv[])
    {
    	char a = 0xff;
    	if (a == 0xff)
    	{
    		printf("equal
    ");
    	}
    
    	return 0;
    }
    执行的结果是, “equal”并没有打印出来。

    你可能已经分析出原因了。字符a在和0xff比較时,被隐式的转换成int(由于0xff是整型),然后a做了符号位扩展。变为0xffffffff, 这个值和0x000000ff比較。当然是不等的。


    我想有讲清楚,欢迎拍砖。

    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    安装提示设备为允许启用的解决办法
    xargs命令
    MariaDB链接超时优化
    灵活QinQ配置
    批量删除.pyo后缀的文件
    netcat的使用
    xxe(xml外部实体注入)
    渗透测试前:信息收集
    windows文件命名特性利用漏洞
    ssrf(Server-Side Request Forgery)
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4816835.html
Copyright © 2020-2023  润新知