mirror of
https://github.com/krahets/hello-algo.git
synced 2026-08-18 22:40:59 +00:00
deploy
This commit is contained in:
@@ -4672,8 +4672,8 @@
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
& 1 + (-2) \newline
|
||||
& \rightarrow 0000 \. 0001 + 1000 \. 0010 \newline
|
||||
& = 1000 \. 0011 \newline
|
||||
& \rightarrow 0000 \; 0001 + 1000 \; 0010 \newline
|
||||
& = 1000 \; 0011 \newline
|
||||
& \rightarrow -3
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
@@ -4681,38 +4681,38 @@
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
& 1 + (-2) \newline
|
||||
& \rightarrow 0000 \. 0001 \. \text{(прямой код)} + 1000 \. 0010 \. \text{(прямой код)} \newline
|
||||
& = 0000 \. 0001 \. \text{(обратный код)} + 1111 \. 1101 \. \text{(обратный код)} \newline
|
||||
& = 1111 \. 1110 \. \text{(обратный код)} \newline
|
||||
& = 1000 \. 0001 \. \text{(прямой код)} \newline
|
||||
& \rightarrow 0000 \; 0001 \; \text{(прямой код)} + 1000 \; 0010 \; \text{(прямой код)} \newline
|
||||
& = 0000 \; 0001 \; \text{(обратный код)} + 1111 \; 1101 \; \text{(обратный код)} \newline
|
||||
& = 1111 \; 1110 \; \text{(обратный код)} \newline
|
||||
& = 1000 \; 0001 \; \text{(прямой код)} \newline
|
||||
& \rightarrow -1
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
<p>С другой стороны, **в прямом коде у нуля есть два представления: <span class="arithmatex">\(+0\)</span> и <span class="arithmatex">\(-0\)</span> **. Это означает, что числу ноль соответствуют два разных двоичных кода, что может приводить к неоднозначности. Например, если в условном выражении не различать положительный и отрицательный ноль, можно получить ошибочный результат. А если специально обрабатывать такую неоднозначность, придется вводить дополнительные проверки, что может снизить вычислительную эффективность компьютера.</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
+0 & \rightarrow 0000 \. 0000 \newline
|
||||
-0 & \rightarrow 1000 \. 0000
|
||||
+0 & \rightarrow 0000 \; 0000 \newline
|
||||
-0 & \rightarrow 1000 \; 0000
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
<p>Как и прямой код, обратный код тоже страдает от неоднозначности положительного и отрицательного нуля, поэтому компьютеры ввели <u>дополнительный код (2's complement)</u>. Сначала посмотрим на процесс преобразования отрицательного нуля из прямого кода в обратный, а затем в дополнительный:</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
-0 \rightarrow \. & 1000 \. 0000 \. \text{(прямой код)} \newline
|
||||
= \. & 1111 \. 1111 \. \text{(обратный код)} \newline
|
||||
= 1 \. & 0000 \. 0000 \. \text{(дополнительный код)} \newline
|
||||
-0 \rightarrow \; & 1000 \; 0000 \; \text{(прямой код)} \newline
|
||||
= \; & 1111 \; 1111 \; \text{(обратный код)} \newline
|
||||
= 1 \; & 0000 \; 0000 \; \text{(дополнительный код)} \newline
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
<p>При добавлении <span class="arithmatex">\(1\)</span> к обратному коду отрицательного нуля возникает перенос, но длина типа <code>byte</code> составляет всего 8 бит, поэтому переполнившаяся в 9-й бит единица отбрасывается. Иными словами, <strong>дополнительный код отрицательного нуля равен <span class="arithmatex">\(0000 \. 0000\)</span> и совпадает с дополнительным кодом положительного нуля</strong>. Значит, в представлении дополнительного кода существует только один ноль, и проблема неоднозначности положительного и отрицательного нуля тем самым устраняется.</p>
|
||||
<p>При добавлении <span class="arithmatex">\(1\)</span> к обратному коду отрицательного нуля возникает перенос, но длина типа <code>byte</code> составляет всего 8 бит, поэтому переполнившаяся в 9-й бит единица отбрасывается. Иными словами, <strong>дополнительный код отрицательного нуля равен <span class="arithmatex">\(0000 \; 0000\)</span> и совпадает с дополнительным кодом положительного нуля</strong>. Значит, в представлении дополнительного кода существует только один ноль, и проблема неоднозначности положительного и отрицательного нуля тем самым устраняется.</p>
|
||||
<p>Остается последний вопрос: диапазон типа <code>byte</code> равен <span class="arithmatex">\([-128, 127]\)</span> , откуда берется лишнее отрицательное число <span class="arithmatex">\(-128\)</span> ? Мы замечаем, что у всех целых чисел из интервала <span class="arithmatex">\([-127, +127]\)</span> есть соответствующие прямой, обратный и дополнительный коды, а прямой и дополнительный коды можно преобразовывать друг в друга.</p>
|
||||
<p>Однако <strong>дополнительный код <span class="arithmatex">\(1000 \. 0000\)</span> является исключением: у него нет соответствующего прямого кода</strong>. Согласно правилу преобразования, прямой код для этого дополнительного кода должен быть равен <span class="arithmatex">\(0000 \. 0000\)</span> . Это очевидное противоречие, потому что такой прямой код обозначает число <span class="arithmatex">\(0\)</span> , а его дополнительный код должен совпадать с ним самим. Компьютер просто определяет, что этот особый дополнительный код <span class="arithmatex">\(1000 \. 0000\)</span> представляет число <span class="arithmatex">\(-128\)</span> . На самом деле результат вычисления <span class="arithmatex">\((-1) + (-127)\)</span> в дополнительном коде как раз и равен <span class="arithmatex">\(-128\)</span> .</p>
|
||||
<p>Однако <strong>дополнительный код <span class="arithmatex">\(1000 \; 0000\)</span> является исключением: у него нет соответствующего прямого кода</strong>. Согласно правилу преобразования, прямой код для этого дополнительного кода должен быть равен <span class="arithmatex">\(0000 \; 0000\)</span> . Это очевидное противоречие, потому что такой прямой код обозначает число <span class="arithmatex">\(0\)</span> , а его дополнительный код должен совпадать с ним самим. Компьютер просто определяет, что этот особый дополнительный код <span class="arithmatex">\(1000 \; 0000\)</span> представляет число <span class="arithmatex">\(-128\)</span> . На самом деле результат вычисления <span class="arithmatex">\((-1) + (-127)\)</span> в дополнительном коде как раз и равен <span class="arithmatex">\(-128\)</span> .</p>
|
||||
<div class="arithmatex">\[
|
||||
\begin{aligned}
|
||||
& (-127) + (-1) \newline
|
||||
& \rightarrow 1111 \. 1111 \. \text{(прямой код)} + 1000 \. 0001 \. \text{(прямой код)} \newline
|
||||
& = 1000 \. 0000 \. \text{(обратный код)} + 1111 \. 1110 \. \text{(обратный код)} \newline
|
||||
& = 1000 \. 0001 \. \text{(дополнительный код)} + 1111 \. 1111 \. \text{(дополнительный код)} \newline
|
||||
& = 1000 \. 0000 \. \text{(дополнительный код)} \newline
|
||||
& \rightarrow 1111 \; 1111 \; \text{(прямой код)} + 1000 \; 0001 \; \text{(прямой код)} \newline
|
||||
& = 1000 \; 0000 \; \text{(обратный код)} + 1111 \; 1110 \; \text{(обратный код)} \newline
|
||||
& = 1000 \; 0001 \; \text{(дополнительный код)} + 1111 \; 1111 \; \text{(дополнительный код)} \newline
|
||||
& = 1000 \; 0000 \; \text{(дополнительный код)} \newline
|
||||
& \rightarrow -128
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
|
||||
Reference in New Issue
Block a user