关于符号位扩展你又知道多少
来源:互联网 发布:c一维数组排序算法 编辑:程序博客网 时间:2024/05/29 14:07
转载请注明出处
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\n", s1);
- printf("s2 = %d\n", 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\n", s1);
- System.out.printf("s2 = %d\n", 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\n", s1);
- printf("s2 = %d\n", s2);
- return 0;
- }
趁热打铁,再看一个示例:
- int _tmain(int argc, _TCHAR* argv[])
- {
- char a = 0xff;
- if (a == 0xff)
- {
- printf("equal\n");
- }
- return 0;
- }
我希望已经讲清楚了,欢迎拍砖。
0 0
- 关于符号位扩展你又知道多少
- 关于符号位扩展你又知道多少
- "&"符号你知道多少
- 关于 ImageX 你知道多少
- 关于UITableView,你知道多少
- 关于脚 ,你知道多少
- 关于UITableView,你知道多少
- 关于PreparedStatement你知道多少
- 关于商务礼仪,你知道多少
- 关于PreparedStatement你知道多少
- 关于PreparedStatement你知道多少
- 关于 Mesos,你知道多少?
- 关于#define你知道多少?
- 关于条形码,你知道多少?
- js经常用到的美元符号$ 你知道多少
- 关于Java String,你知道多少?
- 关于端口号你知道多少!
- 关于Java IO流 你知道多少
- RDD持久化、广播、累加器
- windows程序设计(第五版)笔记-001
- python 二进制,十进制,十六进制
- 配置Ceph为openstack后端
- 浮点数的理解和BigDecimal的使用
- 关于符号位扩展你又知道多少
- bzoj2002
- iOS9 中不支持http
- 我对递归的认识
- MySQL 常用日期和时间处理函数
- iTerm2 快捷键
- 密码学(2)-古典密码学
- DotNet中StringBuilder和String的区别
- 数据结构实现之索引优先队列用例(多路归并)