2020-10-12 ゞ 浴缸里的玫瑰 2022-12-13 14:26 110阅读 0赞 # 补码的由来 # 我们知道,假如进行10进制的14-14,结果等于0,这很容易实现,那么计算机内部是如何处理的呢,我们知道计算机进行加法运算的时候,直接是将原码进行相加即可得到正确的结果,那么14-14直接进行原码的操作会发生什么呢? 将进制进行转化得到 14D = 00001110B -14D = 10001110B 00001110 + 10001110 ----------- 10011100 10 - 2 = 8; // 我们需要将时钟拨快10个小时 10+10=20 // 拨快10小时后时间变为了20点,因为时钟一圈的总数是12,所以超过20是没有意义的,那么就要减去12 // 那么此处为什么要取模运算呢,因为可能超过12的数量可以是很多很多圈,例如超过了2个12小时 20/12=8 a 10 - 2 = 8 b (10 + 10) / 12 = 8//实际上,模以12操作,是自然进行的,我们并没有去进行此项操作 B 10 + 10 = 8 c (10 + (12 - 2)) / 12 = 8 C 10 + (12 - 2) = 8 00001110 +10001110 因为有符号位,我们计算的结果是错误的,所以我们希望转化为两个无符号的数字,通过上面的分析,我们希望转化为下面 00001110 -00001110 此时去掉了符号位,如果直接相减,得到的结果0就是我们想要的结果,但是此时需要计算机实现符号位的自动处理,这在实现上会很复杂,但是通过上面的分析我们可以得到下面的式子 00001110 -00001110 ----———————————————————————————— ⬇️ 00001110 + 100000000 - 00001110 ----———————————————————————————— ⬇️ 00001110 + (00000001+01111111)-10001110 ----———————————————————————————— ⬇️ 00001110 + 00000001+(01111111-10001110) ----———————————————————————————— 100000000-00001110 = (00000001+01111111)-10001110 = 00000001+(01111111-10001110) = 11110010 00001110 +11110010 ---------- 100000000 192-64 192+256-64 11000000 +100000000 - 01000000 ------------------------------------------------------------------ ⬇️ 11000000 + 00000001 + 01111111 - 01000000 ------------------------------------------------------------------ ⬇️ 11000000 + 00000001 +(01111111 - 01000000) ------------------------------------------------------------------ ⬇️ 11000000 + 00000001 +00111111 ------------------------------------------------------------------ ⬇️ 11000000 +01000000 ------------------------------------------------------------------ 10000000 10000000B=128,此时,时钟又回到了128点,我们的结果正确了 192+256-64 = 192+(256-64) =192+(1+255-64) = 192+(1+(255-64)),我们换成二进制的计其数的写法,应该是这样的 我们知道这两个式子的计算结果是相等的,于是就按照第二个式子进行做吧 其实我们完全可以忘掉上面的时钟,我们想象一下每天有256个小时,那么我们的钟表是这样的,我认为这样更好理解一些。接下来还是按照很笨的方法进行计算 这其中,我们经历了数字的拆分,运算的合并,就像小学时候的快速运算法(9+6+4=?,我们就会先运算6+4),至此我们明白了为什么负数的反码等于按位取反之后再加上1了。 于是我们把这一系列的过程得到的机器码叫做反码,并且知道了,反码的值等于按位取反之后,再加上数字1,这一列的操作可以用下面的这幅图来表示 * 把一个负数(-a)等价换算为模-这个数字的绝对值,即 100000000-a * 把100000000 等价为00000001+01111111 * 此时计算01111111-a,此时得到的结果是a的按位取反的值 * 加上最前面的数字00000001,即再加上1 此时我们进行取模运算100000000/256=0,其实不进行取模运算的话,一个字节的长度只有8位,最高位的1已经被舍弃了,式子的结果还是等于0,于是我们实现了14+(-14)的机器运算的正确结果,此时回忆一下这个式子我们做了什么 如果我们先计算括号中的式子就会发现,得到的数字就是-14的按位取反,即每一个比特上面的数字全部取反,那么最后再加上最前面的1,我们可以得到如下的式子 因为100000000 = 00000001+01111111,所以我们把100000000 - 00001110 拆成了(00000001+01111111)-10001110,为什么要这样拆呢,是因为我们为了拆成最后的式子,即 其实,我们还可以有一个更好的理解,不去计算到底要走快多少时间,我们认为我们的智商很低,让钟表再走快12小时,那么就是10+12,也就是又多转了一圈,那么还是走到了10点,然后再倒退两小时,那么结果还是10+12-2,然后我们只要改变一下运算顺序就可以了,即10+(12-2),接下里的步骤就是对(12-2)这个式子进行拆拆补补。 接下来我们看看我们会得到怎么样的结论 另外一种笨的办法就是让他走快一些,快多少呢,我们需要拨快的时间是12-2=10小时 我们都知道生活中的时钟的例子,假如现在的时间是10点,并且假如我们的钟表快了2小时,那么我们最容易想到的办法就是往回倒走2小时,我们通常会想到的算式是: 那么此时的10011100B=?,计算结果是-28,这显然跟我们的预期不相符合。 我们知道14-14 = 14+(-14),计算一下得知
相关 算法 - Leetcode - 练习题目 - 记录 - 20201012 1.应用场景 <table> <tbody> <tr> <td>主要用于记录个人leetcode解题过程。</td> </tr> </tbody> 待我称王封你为后i/ 2022年12月14日 03:41/ 0 赞/ 176 阅读
还没有评论,来说两句吧...