This commit is contained in:
krahets
2023-08-20 23:28:04 +08:00
parent 26a2e7f171
commit 47b7d6fd44
49 changed files with 161 additions and 162 deletions

View File

@@ -3417,8 +3417,8 @@
<p>在本书中,标题带有的 * 符号的是选读章节。如果你时间有限或感到理解困难,可以先跳过,等学完必读章节后再单独攻克。</p>
</div>
<h2 id="331">3.3.1 &nbsp; 原码、反码和补码<a class="headerlink" href="#331" title="Permanent link">&para;</a></h2>
<p>上一节的表格中我们发现,所有整数类型能够表示的负数都比正数多一个例如<code>byte</code> 的取值范围是 <span class="arithmatex">\([-128, 127]\)</span> 。这个现象比较反直觉,它的内在原因涉及到原码、反码、补码的相关知识。</p>
<p>在展开分析之前,我们首先给出三者的定义:</p>
<p>上一节的表格中我们发现,所有整数类型能够表示的负数都比正数多一个例如 <code>byte</code> 的取值范围是 <span class="arithmatex">\([-128, 127]\)</span> 。这个现象比较反直觉,它的内在原因涉及到原码、反码、补码的相关知识。</p>
<p>实际上,<strong>数字是以“补码”的形式存储在计算机中的</strong>。在分析这样做的原因之前,我们首先给出三者的定义:</p>
<ul>
<li><strong>原码</strong>:我们将数字的二进制表示的最高位视为符号位,其中 <span class="arithmatex">\(0\)</span> 表示正数,<span class="arithmatex">\(1\)</span> 表示负数,其余位表示数字的值。</li>
<li><strong>反码</strong>:正数的反码与其原码相同,负数的反码是对其原码除符号位外的所有位取反。</li>
@@ -3427,8 +3427,7 @@
<p><img alt="原码、反码与补码之间的相互转换" src="../number_encoding.assets/1s_2s_complement.png" /></p>
<p align="center"> 图:原码、反码与补码之间的相互转换 </p>
<p>显然「原码」最为直观。但实际上,<strong>数字是以「补码」的形式存储在计算机中的</strong>。这是因为原码存在一些局限性</p>
<p>一方面,<strong>负数的原码不能直接用于运算</strong>。例如,我们在原码下计算 <span class="arithmatex">\(1 + (-2)\)</span> ,得到的结果是 <span class="arithmatex">\(-3\)</span> ,这显然是不对的。</p>
<p>「原码 true form」虽然最直观但存在一些局限性。一方面<strong>负数的原码不能直接用于运算</strong>。例如在原码下计算 <span class="arithmatex">\(1 + (-2)\)</span> ,得到的结果是 <span class="arithmatex">\(-3\)</span> ,这显然是不对的</p>
<div class="arithmatex">\[
\begin{aligned}
&amp; 1 + (-2) \newline
@@ -3437,7 +3436,7 @@
&amp; = -3
\end{aligned}
\]</div>
<p>为了解决此问题,计算机引入了「反码」。如果我们先将原码转换为反码,并在反码下计算 <span class="arithmatex">\(1 + (-2)\)</span> ,最后将结果从反码转化回原码,则可得到正确结果 <span class="arithmatex">\(-1\)</span></p>
<p>为了解决此问题,计算机引入了「反码 1's complement code」。如果我们先将原码转换为反码,并在反码下计算 <span class="arithmatex">\(1 + (-2)\)</span> ,最后将结果从反码转化回原码,则可得到正确结果 <span class="arithmatex">\(-1\)</span></p>
<div class="arithmatex">\[
\begin{aligned}
&amp; 1 + (-2) \newline
@@ -3455,7 +3454,7 @@
-0 &amp; = 1000 \space 0000
\end{aligned}
\]</div>
<p>与原码一样,反码也存在正负零歧义问题,因此计算机进一步引入了「补码」。我们先来观察一下负零的原码、反码、补码的转换过程:</p>
<p>与原码一样,反码也存在正负零歧义问题,因此计算机进一步引入了「补码 2's complement code」。我们先来观察一下负零的原码、反码、补码的转换过程:</p>
<div class="arithmatex">\[
\begin{aligned}
-0 = \space &amp; 1000 \space 0000 \space \text{(原码)} \newline