个人对于补码的一些理解
2018-04-01 22:55
531 查看
写在前面:
所有的内容都是按照个人理解写成,请大家批判看待。
一、基础概念原码, 反码, 补码 详解
这篇文章清楚的讲解了基础概念,也做了一些数学上的说明。
二、原码有何问题? 由于计算机位数的限制,在一般的编程语言中,整数所表示的范围都是有限的。java中,整数是32位,所以最多能表示2^32个数。人类最容易想到的就是原码的表示方式:第一位数用来表示正负,后面的位数用来表示值,表示的范围为-(2^31-1) ~(2^31-1)。这种表示方式对于人类的理解非常友好。但是,对于计算机来说怎么样呢?这种编码方式下怎么进行加减计算呢?a+b(a,b可正可负,所以加减法情况都包括了)的计算可以分为以下两种情况进行讨论: 1)a * b > 0:即ab同为正或同为负。那么需要保持符号位不变,数值位直接相加。向上溢出(结果大于2^31-1)会从+0开始重新循环,向下溢出(结果小于-(2^31-1))会从-0开始循环。
2)a * b < 0:即ab异号。那么需要先判断ab的数据谁大。决定结果是正还是负。然后数值位大的送去数值位小的。
这.....是不是太麻烦了一点(以上是个人分析,不保证是最优方法),如果所以计算机进行的加减操作都需要进行这么多种判断,那效率实在是堪忧。再者,当发生溢出时,我们期望的规则是什么?当然,我们期望的溢出规则是像时钟一样,从12向上溢出变为0,从0向下溢出变为12。 那么有没有一种编码方法,可以
d1e7
保证满足我们的溢出规则,同时又保持高效呢?答案是肯定的,这就是我们的补码。下面我将按照我的理解分析分析补码为什么高效。
三、补码有啥好处?
整数最大值:01111111 11111111 11111111 11111111 加1,变成了:10000000 00000000 00000000 00000000。我们希望加1能够向上溢出表示最小值,那么让10000000 00000000 00000000 00000000这个值表示最小值如何呢?取消之前的符号位定义,将第一位定义成:-k*2^31(k表示第一位的数值,为0或1)。后面的每一位都跟原码含义一样。这样,上界加1溢出到下界,下界减1溢出到上界,貌似很完美,那么进行加法运算呢?以a+b来进行说明。 1) a>=0&& b>=0,所有位直接相加即可得到正确结果。(如果发生溢出则上界溢出到下界) 2) a>=0 && b< 0。又分为|a| > |b|和|b|>|a|两种情况。
|a| > |b| 直接相加。 a低31位的值为|a|,b的低31位值为2^w-|b|。因为|a|>|b|,所以低31位相加会发生溢出。所以最高位结果最终为0,低31位结果为|a|-|b|。跟真实结果相符。 |a| < |b| 直接相加。 a低31位的值为|a|,b的低31位值为2^w-|b|。因为|a|<|b|,所以低31位相加不会发生溢出。所以最高位结果最终为1,低31位结果为2^31-|b|+|a|。跟真实结果相符。 3)a<0 && b<0 |a| + |b| < 2^31。直接相加。 a低31位的值为2^31-|a|,b的低31位值为2^31-|b|。因为 |a| + |b| < 2^31,所以2^31-|a|-|b|不会溢出。将其中一个2^31向高位进1,所以最高位结果最终为1,低31位结果为2^31-|a|-|b|。跟真实结果相符。 |a| + |b| > 2^31。直接相加。 a低31位的值为2^31-|a|,b的低31位值为2^31-|b|。因为 |a| + |b| > 2^31,所以2^31+2^31-|a|-|b|才不会溢出,0<2^31+2^31-|a|-|b|<2^31。所以最高位结果最终为1,低31位结果为2^31+2^31-|a|-|b|。最终结 果为正。跟真实结果相符。 所以,最最重要的结论出现了。补码的加减法运行全部都可以当做按位相加的加法来进行运算,不管数的正负,也不管结果的正负,不需要关心最高位是0还是1,只要用补码表示,就能得到正确结果。天啦,简直太神奇了,太完美了。四、补码是咋发明的? 这个真不知道。也许就是这么凑出来的,也许背后有着精妙的数学逻辑,也许补码的正确性也有简洁而又美的证明。这些,等我以后学到了再来补充^_^。
所有的内容都是按照个人理解写成,请大家批判看待。
一、基础概念原码, 反码, 补码 详解
这篇文章清楚的讲解了基础概念,也做了一些数学上的说明。
二、原码有何问题? 由于计算机位数的限制,在一般的编程语言中,整数所表示的范围都是有限的。java中,整数是32位,所以最多能表示2^32个数。人类最容易想到的就是原码的表示方式:第一位数用来表示正负,后面的位数用来表示值,表示的范围为-(2^31-1) ~(2^31-1)。这种表示方式对于人类的理解非常友好。但是,对于计算机来说怎么样呢?这种编码方式下怎么进行加减计算呢?a+b(a,b可正可负,所以加减法情况都包括了)的计算可以分为以下两种情况进行讨论: 1)a * b > 0:即ab同为正或同为负。那么需要保持符号位不变,数值位直接相加。向上溢出(结果大于2^31-1)会从+0开始重新循环,向下溢出(结果小于-(2^31-1))会从-0开始循环。
2)a * b < 0:即ab异号。那么需要先判断ab的数据谁大。决定结果是正还是负。然后数值位大的送去数值位小的。
这.....是不是太麻烦了一点(以上是个人分析,不保证是最优方法),如果所以计算机进行的加减操作都需要进行这么多种判断,那效率实在是堪忧。再者,当发生溢出时,我们期望的规则是什么?当然,我们期望的溢出规则是像时钟一样,从12向上溢出变为0,从0向下溢出变为12。 那么有没有一种编码方法,可以
d1e7
保证满足我们的溢出规则,同时又保持高效呢?答案是肯定的,这就是我们的补码。下面我将按照我的理解分析分析补码为什么高效。
三、补码有啥好处?
整数最大值:01111111 11111111 11111111 11111111 加1,变成了:10000000 00000000 00000000 00000000。我们希望加1能够向上溢出表示最小值,那么让10000000 00000000 00000000 00000000这个值表示最小值如何呢?取消之前的符号位定义,将第一位定义成:-k*2^31(k表示第一位的数值,为0或1)。后面的每一位都跟原码含义一样。这样,上界加1溢出到下界,下界减1溢出到上界,貌似很完美,那么进行加法运算呢?以a+b来进行说明。 1) a>=0&& b>=0,所有位直接相加即可得到正确结果。(如果发生溢出则上界溢出到下界) 2) a>=0 && b< 0。又分为|a| > |b|和|b|>|a|两种情况。
|a| > |b| 直接相加。 a低31位的值为|a|,b的低31位值为2^w-|b|。因为|a|>|b|,所以低31位相加会发生溢出。所以最高位结果最终为0,低31位结果为|a|-|b|。跟真实结果相符。 |a| < |b| 直接相加。 a低31位的值为|a|,b的低31位值为2^w-|b|。因为|a|<|b|,所以低31位相加不会发生溢出。所以最高位结果最终为1,低31位结果为2^31-|b|+|a|。跟真实结果相符。 3)a<0 && b<0 |a| + |b| < 2^31。直接相加。 a低31位的值为2^31-|a|,b的低31位值为2^31-|b|。因为 |a| + |b| < 2^31,所以2^31-|a|-|b|不会溢出。将其中一个2^31向高位进1,所以最高位结果最终为1,低31位结果为2^31-|a|-|b|。跟真实结果相符。 |a| + |b| > 2^31。直接相加。 a低31位的值为2^31-|a|,b的低31位值为2^31-|b|。因为 |a| + |b| > 2^31,所以2^31+2^31-|a|-|b|才不会溢出,0<2^31+2^31-|a|-|b|<2^31。所以最高位结果最终为1,低31位结果为2^31+2^31-|a|-|b|。最终结 果为正。跟真实结果相符。 所以,最最重要的结论出现了。补码的加减法运行全部都可以当做按位相加的加法来进行运算,不管数的正负,也不管结果的正负,不需要关心最高位是0还是1,只要用补码表示,就能得到正确结果。天啦,简直太神奇了,太完美了。四、补码是咋发明的? 这个真不知道。也许就是这么凑出来的,也许背后有着精妙的数学逻辑,也许补码的正确性也有简洁而又美的证明。这些,等我以后学到了再来补充^_^。
相关文章推荐
- 对于angular 中MVC 和 MVVM 的一些个人理解
- 个人对于OO的一些理解
- 对于NHibernate中延迟加载个人的一些理解
- 个人对于套接字的一些理解!
- 对于Java转型的一些个人理解
- 对于AOP切面编程的一些个人理解
- 对于CN Payroll我的一些个人理解
- 个人对于OO的一些理解
- python的平台编码、默认编码、解码直接的联系的一些个人理解
- 对于nginx $request_time的一些理解
- 对于堆排序的一些理解!
- 数据库水平分库的一些个人理解
- Java关于个人对于Socket的理解,Socket多线程批量上传文件,适合新手
- 对于IO流的个人理解
- 对于dequeueReusableCellWithIdentifier:的个人理解
- 转 本人对于“用例”的一些理解和总结
- 个人对于线程安全的理解(内容会不断更新,只是个人理解,不具备权威性)
- 个人对于数组和缓冲区的理解
- 关于CPU 架构与指令集的一些个人理解
- 对于String类中的"abc"与new String("abc")的一些理解