软讯网络 > 编程语言 > C/C++ > 【CSAPP读书笔记】(一)计算机内数据的表示方式(转载)
【标 题】:【CSAPP读书笔记】(一)计算机内数据的表示方式(转载)
【关键字】:
CSAPP
【来 源】:http://blog.chinaunix.net/article.php?articleId=35826&blogId=5727
【CSAPP读书笔记】(一)计算机内数据的表示方式(转载)
【CSAPP读书笔记】(一)计算机内数据的表示方式
摘自converse 的CU博客http://blog.chinaunix.net/index.php?blogId=902
【CSAPP读书笔记】(一)计算机内数据的表示方式 |
| converse 发表于 2004年11月03日16时02分 |
一、整数的表示法 无符号和有符号数表示的一点理解 有三个数的表示方法如下: 12345: 0011 0000 0011 1001 (补码表示) -12345: 1100 1111 1100 0111 (补码表示) 53191: 1100 1111 1100 0111 (无符号表示) 可以发现如下的规律: 1)12345和-12345的补码表示相加为 0001 0000 0000 0000 0000,即2的16次幂。 2)-12345的补码表示和53191的无符号表示相同,而-12345的绝对值与53191之和为65536, 同样是2的16次幂。 以上的现象可以这样解释:(为减少问题的难度设数据为8位的,2的8次幂为256) 把2的8次幂看作是钟的最大格数,那么无符号数的表示法就是从一个方向(这里 定为顺时针方向)转遍这个钟,总共要走256格,也就是说无符号数的表示范围从0~2的8次幂 - 1。 而补码表示法就是从两个方向转,一个顺时针方向,定为正方向,逆时针方向定为负方向,两个方向 都只能转到钟的一半的地方,正方向上的最大值为127,即是0x7F,负方向上的绝对值最大的值是 -128,即是0x80,可以看出0x7F加上1就是0x80了,就是说从正方向转到最大的位置之后再往正方向 转一个格进入了负方向表示的范围之中了。 下面来解释前面的两个规律。 1)为什么绝对值相同的数补码相加是钟的最大格数(即表示范围)? 原因很简单,首先向正方向转一个角度,再向负方向转同一个大小的角度,那么肯定就是回到原来的 位置,在这里原来的起点位置就是2的8次幂。这个规律也说明了求一个负数的补码表示的一种方法: 首先写出这个负数的绝对值的补码表示,如果是n位大小的,那么用2的n次幂的二进制表示减去 这个负数的绝对值的补码表示就可以得出这个负数的补码表示了。也或者像在有的书中 (如《IBM-PC汇编语言程序设计》)说的那样:先写出与改负数相对应的正数的补码表示,然后按位 求反,最后在末尾(最低位)加一就可以得到改负数的补码表示了。 2)为什么一个数的补码表示法用无符号表示法解释之后两者的绝对值相加是钟的最大格数? 两者有相同的二进制表示(可以理解为在钟上的位置相同),只是解释不同罢了,一个无符号一个是 补码,也就是说一个是顺时针一个是逆时针,不要忘了钟是一个圆,因此这两者转过的格数相加就是 钟的格数,即这个系统中数字所能表示的范围了。简而言之,就是说要转到钟上的任一个位置,可以 正着转也可以逆着转,效果(位置相同,二进制表示相同),但是方式(转的方向,对二进制数的 解释不同)。也可以通过这个规律得出求负数补码表示的另一种办法,不再详述。 两者之间的关系,可以用下面的公式表示,x表示一个补码数,而u表示与x相对应的无符号数: u = x (x >= 0) 或 x + 2的n次幂(x < 0)。 printf函数本身并不能分辩出参数的类型,只是根据格式化的参数对输入的数进行解释,格式不同 解释出来的数就不同。比方下面的程序: int x = -12345; printf("x = %hdn", x); /* 输出-12345 */ printf("x = %hun", x); /* 输出53191 */ 因此,使用printf输出数的时候要与数据的类型相对应,否则结果很可能出错。
在执行一个运算时,如果运算数中有一个是无符号的,那么c会隐含的将有符号的数强制转换成无符号 数,并且假设数都是非负的来执行这个操作。比如 -1 < 0U。 二、浮点数的表示法 书上写的很详细了,网上还可以找到关于这个问题的文档有: http://purec.binghua.com/Soft/UploadSoft/200409/20040910140933723.rar http://bbs.chinaunix.net/forum/viewtopic.php?t=343975&show_type=new |
【相关文章】
没有相关文章