Читаем Код. Тайный язык информатики полностью

Одна из проблем этой техники заключается в том, что для деления вы, вероятно, решите использовать калькулятор, а калькуляторы не показывают остаток от деления. Если вы разделите 31 148 на 4096 на калькуляторе, то получите 7,6044921875. Чтобы рассчитать остаток, нужно умножить 4096 на 7 (получится 28 672) и вычесть это значение из 31 148. Или умножить 4096 на 0,6044921875 — дробную часть результата от деления. (Правда, некоторые калькуляторы предусматривают функцию преобразования десятичных чисел в шестнадцатеричные и обратно.)

Другой способ преобразования десятичных чисел от 0 до 65 535 в шестнадцатеричные предполагает разделение числа на два байта путем его деления на 256. Затем каждый байт делится на 16. Шаблон для этого следующий.

Начнем сверху. После каждой операции деления частное помещается в прямоугольник, расположенный слева от делителя, а остаток — в прямоугольник справа. Например, число 51 966 преобразуется таким образом.

Шестнадцатеричными эквивалентами чисел 12, 10, 15 и 14 являются буквы С, А, F и Е, поэтому результат скорее напоминает слово, чем число.

Далее представлена таблица сложения для шестнадцатеричной системы счисления.

Используя эту таблицу и обычные правила сложения в столбик, можно складывать шестнадцатеричные числа.

В главе 13 я упоминал, что для представления отрицательных чисел можно применять дополнение до двойки. Если вы имеете дело с 8-битными двоичными числами со знаком, то отрицательные числа начинаются с 1. В шестнадцатеричной системе счисления двузначные числа со знаком отрицательные, если они начинаются с цифр 8, 9, A, B, C, D, E или F, поскольку их двоичные эквиваленты начинаются с 1. Например, число 99h может соответствовать либо десятичному числу 153 (если вы знаете, что имеете дело с однобайтными числами без знака), либо десятичному числу –103 (если вы знаете, что это число со знаком).

Кроме того, байт 99h может соответствовать и десятичному числу 99. Это интересно, но, похоже, противоречит всему, о чем мы говорили до сих пор. В главе 23 объясню, как это работает, а теперь остановимся на памяти.

<p>Глава 16</p><p>Сборка памяти</p>

Каждое утро, когда мы просыпаемся, включается наша память. Мы вспоминаем, где находимся, что делали накануне, что планируем сделать сегодня. Память возвращается сразу или фрагментами, и в течение еще нескольких минут человек может чего-то не помнить («Забавно, я не помню, что лег спать в носках»), однако в целом мы способны восстановить непрерывность своей жизни, чтобы начать новый день.

Разумеется, человеческая память не вполне упорядочена. Попытайтесь вспомнить что-нибудь из школьного курса геометрии. Вероятно, начнете думать о сидевшем перед вами однокласснике или о том дне, когда сработала пожарная тревога как раз в тот момент, когда учитель собирался объяснить вам, что значит выражение «что и требовалось доказать».

Человеческая память не является вполне надежной. Письменность, возможно, была изобретена специально, чтобы компенсировать недостатки человеческой памяти. Может быть, прошлой ночью вы внезапно проснулись в 3:00 с отличной идеей для сценария. Схватили ручку и бумагу, которые держите у кровати специально для таких случаев, и записали идею. На следующее утро вы читаете свою блестящую мысль и начинаете работу над сценарием («Парень встречает девушку, погоня на машинах и взрывы»… и это всё?). Или не начинаете.

Мы пишем, а затем читаем. Мы сохраняем, а потом извлекаем. Мы храним информацию, а в дальнейшем получаем к ней доступ. Функция памяти заключается в том, чтобы сохранять информацию без искажений между этими двумя событиями. Каждый раз, когда мы сохраняем информацию, мы используем разные типы памяти. Бумага — хороший носитель для хранения текстовой информации, магнитная лента подходит для хранения музыки и фильмов.

Телеграфные реле, будучи объединенными в вентили, а затем в триггеры, также могут хранить информацию. Как мы видели ранее, триггер способен хранить один бит. Это не очень много, но это начало. Как только мы научимся сохранять один бит, мы легко сможем справиться с двумя, тремя и более.

В главе 14 мы познакомились с D-триггером со срабатыванием по уровню, который состоит из инвертора, двух вентилей И и двух вентилей ИЛИ-НЕ.

Когда вход Clk равен 1, выходной сигнал Q совпадает с входным сигналом «Данные». Когда значение входа Clk меняется на 0, выход Q сохраняет последнее значение входа «Данные». Дальнейшие изменения входного сигнала «Данные» не влияют на выходы до тех пор, пока значение входа Clk снова не изменится на 1. Вот таблица логики для триггера.

В главе 14 этот триггер использовался в разных схемах, а сейчас он будет применяться исключительно для хранения одного бита. По этой причине я собираюсь переименовать входы и выходы, чтобы они соответствовали цели.

Перейти на страницу:

Похожие книги