整数在内存中的表达
2016-07-23 12:36
267 查看
http://bbs.chinaunix.net/thread-3765224-1-1.html
很对, 没有问题. 不过我想告诉LZ一个更容易理解的办法. 假设, 我现在只有4 bits空间. 那么这个空间最多能存放2 ^ 4, 即16个数, 也就是 0 - 15. 想像一个表盘, 这个表盘刚好有16个刻度. 这样子, 我们将上面的16个数和表盘对应起来. 对应的结果如下所示. | | 0000 1111 0001 1110 0010 1101 0011 1100 0100 1011 0101 1010 0110 1001 0111 1000 | | 本来表盘是圆形的, 结果上面看上去是菱形的. 将就看吧. 瞧: 这个表盘能够表示16个数字, 所以我们称呼16为这个表盘的模. 同理, 我们称16是4bits的模, 256是8bits的模, etc. 看到上面和下面我分别标的竖线了吗? 那代表我将这个表盘切成了两部分. 这个切法代表什么意思呢? 我们知道表盘能够表示16个数字, 如果我认为这个表盘表示的数字都是正数, 那么我可以不切这个表盘. 不切这表盘就表示, 假设时针从0开始顺时针转, 每过一个小时, 时针就向前一格(假设一天有16个小时, 这也不是什么大事, 呵呵). 于是, 这个表盘可以表示 0 -- 15. 现在我想让这个表盘既可以表示正数, 也可以表示负数. 看, 很简单, 我把这个表盘像上面那样切开, 就像切一个馅饼一样. 我说左半部分你们代表正数吧. 右半部分你们代表负数吧. 于是一切就work了, 我们让时针顺时针转, 顺时针走一格就代表加1. 我们让时钟逆时针转, 逆时针走一格就代表减1.瞧, 正着转一格, 0000 -> 0001. 逆时针转一格, 0000 -> 1111, 等等, 1111是什么? 没错, 1111就是补码的-1. 看, 这个表盘完美地工作, 太妙了. 现在我们来做一件事情. 假设现在时针指向12点(注意, 我们这个表盘一共有16点), 就是指向1100那里. 现在我们想让时钟指到9点, 也就是1001那里. 我们可以用两种方式来做到这一点: 第一种方式是倒拨(逆时针方向)3格. 于是我们有: 12 - 3 = 9. 第二种方式是顺拨13格. 于是我们有: 12 + 13 = 9. 我们看看, -3是谁? 假设我们切开了这个表盘, 那么-3就是1101. 我们再看看, 13是谁? 假设我们没有切开这个表盘, 看, 13也是1101. 于是我们有: 1100 + 1101 = 1001 于是, 明白了吗, 我不需要12 - 3, 那个减号对我来说没用. 我只管知道 1100 + 1101 = 1001就可以了. 没错, 计算机为什么用补码来表示整数,因为用补码来表示整数不需要减法, 我们只要一个硬件加法器就可以了. 同时, 我们还发现一件事情. (12 - 3) % 16 == 9 (12 + 13) % 16 == 9 我们称, 12 - 3 和 12 + 13 共模同余(模16余9), 同时称, 13和3互补(在模为16的前提下), 即互为补数. 看, 算补码也很简单了. 当然了, 比如假设有32 bits, 那么模就是2 ^ 32, 如果有64 bits, 那么模就是 2 ^ 64. 很简单, 我们只需要想象一个大得多的表盘就可以了, 这挺简单的, 不是吗? |
相关文章推荐
- 通过nfs挂载共享目录的方式搭建lamp平台并安装wordpress(一)
- kobject.c 添加注释
- 面试题29:数组中出现次数超过一半的数字
- 最小树形图
- 用Jplayer做的一个带动画的播放器
- 校外分散实习(13)
- 《架构探险》之数据访问层代码优化
- 【VS开发】win7下让程序默认以管理员身份运行
- Java 打印n行杨辉三角数据
- formData的简单使用
- kernel 3.10内核源码分析--hung task机制
- Codeforces Round #364 (Div. 2) E. Connecting Universities(从一棵树上挑出n*2个点,两两匹配,求总距离的最大值)
- iOS 判断App是否第一次启动
- ButterKnife的常用方法
- 优先级队列 priority_queue
- iis 访问需要密码解决
- MySQL5.7安装与配置(YUM)
- [华为编程题] 汽水瓶
- 创建Cordova项目
- 鼠标移入导航下部分条状移动