在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
本文转自:http://www.94cto.com/index/Article/content/id/59973.html 1.引例:
今天在做了一道关于有符号数和无符号数相互转换及其左移/右移的问题,被它们之间的转换原理和位移原理搞得头大了。真的很后悔本科的时候没有认真学习《计算机组成原理》/《计算机操作系统》等计算机基础课程。以下是我根据相关知识回顾和整理的材料,如有和某某的文章有雷同之处,请勿见怪。另外也希望看到这篇文章的同志们能够有所收获吧。 1 #include <cstdio> 2 #include <iostream> 3 using namespace std; 4 5 int main() 6 { 7 unsigned short int ui; 8 signed short int si; 9 ui = (unsigned short int)0x8000u; 10 si = (signed short int)0x8000; 11 printf("ui = %u\n",ui); 12 printf("si = %d\n",si); 13 ui = ui>>1; 14 si = si>>1; 15 printf("ui = %u\n",ui); 16 printf("si = %d\n",si); 17 cout<<"------------------------------"<<endl; 18 19 ui = (unsigned short int)0x8000u; 20 si = (signed short int)0x8000; 21 printf("%u\n",ui); 22 printf("%d\n",si); 23 ui = ((signed short int)ui>>1);//先类型转换,再移位, 24 si = ((unsigned short int)si>>1); 25 printf("%u\n",ui); 26 printf("%d\n",si); 27 cout<<"------------------------------"<<endl; 28 29 ui = (unsigned short int)0x8000u; 30 si = (signed short int)0x8000; 31 printf("%u\n",ui); 32 printf("%d\n",si); 33 ui = ui<<1; 34 si = si<<1; 35 printf("%u\n",ui); 36 printf("%d\n",si); 37 cout<<"-------------------------------"<<endl; 38 39 ui = (unsigned short int)0x8000u; 40 si = (signed short int)0x8000; 41 printf("%u\n",ui); 42 printf("%d\n",si); 43 ui = ((signed short int)ui<<1); 44 si =((unsigned short int)si<<1); 45 printf("%u\n",ui); 46 printf("%d\n",si); 47 return 0; 48 } 运行结果 2.概念 十机制数 负数-1 二进制表达形式:1111 1111 可见-1的二进制的最高位为红色的1,可是为什么其表达形式为1111 1111而不是1000 0001呢?这就关于任何数在计算机内是以补码形式存储问题。下面会介绍的,在此先不详细说明了。 3.存储范围 从前面的介绍可以知道,由于有符号数的最高位被拿来用作符号位,所以它所能够表达的最大数值要小于无符号数所能够表达的最大数值。还是举个例子来说明一下吧: 无符号数:1111 1111 十进制值:255 有符号数:0111 1111 十进制值:127 这是有人可能会提出这样的疑问:有符号数所能够表达的数值范围会不会小于无符号数所能够表达的数值范围呢? 呵呵,答案是否定的!虽然有符号数在表达最大值上的能力减弱了,但是它能够表达负数。负数的个数可以弥补其不足。来让我们比较一下: 一个字节的无符号数的表达数值范围是:[0,255] 一个字节的有符号数的表达数值范围是:[-128,0),[0,127] 可见它们都能够表示256个数。 4.各种码(原码/反码/补码) 有些人也许会这样认为"-1"(双字节)在计算机中的表达形式为1000 0000 0000 0001,可是实际上不是的。计算机是以其补码的形式进行表达的,即“-1”(双字节)的表达形式是1111 1111 1111 1111。 说一下各种码的概念吧。 原码:一个整数,按照绝对值的大小转换成二进制数,最高位为符号位。 反码:将原码除最高位(符号位)外,其余各位按位取反,所得到的二进制码。正数的反码为原码。 补码:反码最低位加1即为补码。 关于负数的补码求法说明一下,先得到其反码,之后将反码加1即可。有些大神根据其原码,闭眼即得,这种能力需要修炼一下啊。 这时有些人可能会说,为什么要引入补码的形式呢?直接按照原码存储不就省事很多吗?嘿嘿,要记住,有些事情并不是你想省事就能省事的。好了来欣赏一下补码的优势吧。 计算机的带符号数用补码表示的优点: 1负数的补码与对应正数的补码之间的转换可以用同一种方法-求补运算完成,可以简化硬件。 2 可将减法变为加法,这样减法就可以用加法器进行计算了。 3 两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。 心算求补(大神求补算法): 从最低位开始至找到的第一个1均不变,符号位不变,这之间的各位“求反”(0变1;1变0)。 原码:1010 1001 补码:1101 0111. 5.有符号数与无符号数的相互转换 无符号整数和有符号整数之间进行强制类型转换时,位模式不改变。 有符号数转换为无符号数时,负数转换为大的正数,相当于在原值上加上2的n次方,而正数保持不变。 无符号数转换为有符号数时,对于小的数将保持原值,对于大的数将转换为负数,相当于原值减去2的n次方。 当表达式中存在有符号数和无符号数类型时,所有的操作都自动转换为无符号类型。可见无符号数的运算优先级高于有符号数。 unsigned int a = 20;
signed int b = -130;
运算一下结果是 b>a 6.转换大餐 有符号数的转换
无符号数的转换
7.各种数据类型所占字节 32位平台下: ps:文中若有不当之处,请指出! |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论