Шестнадцатеричный формат и хранение на жестком диске компьютера: хранится ли он в половине байтов?

3007
J. J.

Позвольте мне предсказать, что я не специалист по компьютерам. Больше всего меня интересует информация.

В разговоре со специалистом по информатике мне сказали, что с помощью шестнадцатеричной системы можно хранить строку десятичных числовых значений, например 73829182093, на жестком диске, занимающем только половину необходимых байтов. По словам специалиста, строка из шести десятичных чисел может храниться в виде 3-х байтов, поскольку каждое число может быть представлено шестнадцатеричной цифрой, размер которой составляет всего 4 бита. Это правильно в отношении хранения на жестком диске? Обратите внимание, я ссылаюсь на хранилище на жестком диске, а не на объем памяти, необходимый для отображения.

Мое предыдущее понимание состоит в том, что вся информация хранилась в двоичном виде (0 и 1) на жестких дисках и в 8-битных блоках на современных компьютерных жестких дисках. И этот шестнадцатеричный используется для облегчения отображения информации, поэтому люди не обязаны читать длинные блоки битов.

Если это так, означает ли это, что в данном сценарии блок из 8 битов на жестком диске в шестнадцатеричном хранилище вместо этого будет кодировать два полубайта данных вместо 8 полных битов для символа, как буква "М"? Или на жестком диске, полубайт фактически представлен с полными 8 битами и затем просто не отображается при отображении?

Спасибо.

4
На самом деле, жесткие диски хранят данные в секторах, например, 512 байт. Изменение одного бита на диске требует перезаписи всего сектора. Ron Maupin 7 лет назад 0
@RonMaupin Но это не имеет значения, и даже это произвольно. С нашей стороны (и «нашей стороной» я рисую эту линию у разработчиков ядра / драйверов) они * кажутся * работающими с байтами, и пока они продолжают это делать, нам на самом деле все равно, каково само хранилище * * реализован. Jason C 7 лет назад 0

3 ответа на вопрос

4
Horn OK Please

Мое предыдущее понимание состоит в том, что вся информация хранилась в двоичном виде (0 и 1) на жестких дисках и в 8-битных блоках на современных компьютерных жестких дисках. И этот шестнадцатеричный используется для облегчения отображения информации, поэтому люди не обязаны читать длинные блоки битов.

Это на 100% правильно. Шестнадцатеричное - это просто представление данных; нет ничего особенного в природе шестнадцатеричной по сравнению с другими форматами. Это не включает сжатие данных или что-то в этом роде.

Я думаю, что ваш друг имел в виду разницу между представлением чисел в виде символьных строк и представлением чисел в виде чисел .

Для целых чисел без знака - которые представляют собой числа в битах (нули и единицы) от 0 до определенного фиксированного максимального числа - максимальное число, которое может быть представлено N битами, равно 2 ^ N, минус 1, при условии, что вы начать с 0.

Итак, если у вас есть 8 бит (или 1 байт), вы можете представлять каждое число от 0 до 255 без потери информации; Вы можете манипулировать этими восемью битами от 0 до 1, чтобы однозначно представлять каждое число от 0 до 255 включительно. Или от 1 до 256, если вы предпочитаете. Это не важно Компьютеры, как правило, представляют их, начиная с 0, хотя.

Если у вас есть 16 бит (2 байта), вы можете представлять каждое число от 0 до 65535 (это 2 ^ 16 - 1). 32 бита, каждое число от 0 до 4294967295. 64 бита, каждое число от 0 до числа 1,8 с девятнадцатью нулями .

Вы можете знать из алгебры, что 2 ^ N - экспоненциальная функция. Это означает, что, даже несмотря на 64 бита только в восемь раз больше битов, чем 8 бит, он может хранить путь, путь, путь больше данных в том, что 8-раз-больше бит, чем число 255*8(что только 2040!). 2040 - это очень небольшое число по сравнению с приблизительно 180000000000000000000. И 64 бита могут хранить КАЖДЫЕ числа от 0 до этого максимума.

Одним интересным следствием целых чисел, хранящихся таким образом, является то, что программист должен заранее решить, насколько большим должно быть хранилище, что, в свою очередь, определяет максимальное число, которое может быть представлено данным целым числом. Если вы попытаетесь сохранить число больше, чем может обработать хранилище, вы получите нечто, называемое переполнением . Это происходит, например, если у вас есть 8-битное целое число, которое установлено на 255, и вы просите компьютер добавить 1 к нему. Ну, вы не можете представить 256 внутри целого числа, диапазон которого составляет от 0 до 255! Что обычно происходит, так это «оборачивается» обратно к началу и возвращается к 0.

Там являются программы, которые выполняют математику в режиме, который называется «произвольной точности», которая автоматически изменяет размер их хранения расти все больше и больше в зависимости от того, насколько велики числа обрабатываемых являются; например, если вы умножили 255 на 100000, ответ должен был бы вырасти за пределы 8 бит и более 16 бит, но вписался бы в 32-битное целое число. Если вы введете число или выполнили математическую операцию, которая выдает число, превышающее максимум для 64-разрядного целого числа, ему придется выделить для него еще больше места.


ОДНАКО - если вы представляете числа в виде строки символов, то каждое число будет занимать столько же места, сколько буква в письменной прозе. «ASDF» и «1234» занимают одно и то же место. «OneTwoThreeFourFive» (19 символов) занимает то же пространство, что и «1234567890123456789». Объем требуемого пространства растет линейно с количеством цифр (или букв, или символов, как правило), которые у вас есть. Это потому, что каждый символ может представлять любой из множества символов в наборе символов, а числа - это просто символы в наборе символов. Определенная последовательность нулей и единиц будет производить число «3», другая последовательность будет производить «4»,

Обычно символы хранятся в 8 или 16 битах, но некоторые кодировки символов либо занимают переменное число бит в зависимости от символа (например, UTF-8), либо всегда занимают большее количество бит (например, UCS-32). ,

Если каждый символ занимает 8 битов, «OneTwoThreeFourFive» и «1234567890123456789» оба занимают 152 бита. Но «1234567890123456789» может помещаться в 64-разрядное целое число без знака, которое ... потребляет только 64 бита . Это экономия 88 бит! И мы даже не использовали никаких приемов «сжатия данных», таких как Zip, 7-Zip, RAR и т. Д.

2
Jason C

Мое предыдущее понимание состоит в том, что вся информация хранилась в двоичном виде (0 и 1) на жестких дисках и в 8-битных блоках на современных компьютерных жестких дисках. И этот шестнадцатеричный используется для облегчения отображения информации, поэтому люди не обязаны читать длинные блоки битов.

Ваше предыдущее понимание совершенно верно, и у меня есть ощущение, что вы уже поняли остальную часть этого ответа, но я хочу объяснить несколько идей, которые люди в любом случае часто смешивают. Я постараюсь быть максимально кратким, но это будет сложно.

Байт, Хранение

Данные обычно хранятся на жестком диске (или в памяти) в 8-битных блоках, называемых байтами. Один бит имеет два возможных значения, которые мы условно обозначаем как 0 и 1. Поэтому один байт имеет 2 8 = 256 возможных значений.

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

Кроме того, поскольку я знаю, что это произойдет, в действительности данные не обязательно хранятся на диске в виде однобайтовых блоков или одного байта за раз. Типичные жесткие диски часто используют более крупные блоки и т. Д. Однако, с точки зрения вашего вопроса, все это не имеет значения. Нам важно только то, что нам кажется, что жесткие диски работают с отдельными байтами. Реальная реализация - интересная тема, но она не затрагивает нас здесь: традиционно люди обычно обсуждают хранение в виде отдельных байтов, и мы, вероятно , люди.

Бинарный, шестнадцатеричный

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

Причина, по которой нам, программистам, также нравится использовать шестнадцатеричное (каждая цифра имеет шестнадцать возможных значений), заключается в том, что это действительно удобно . Так уж получилось, что диапазон, представляемый одной шестнадцатеричной цифрой, точно соответствует диапазону, представленному четырьмя двоичными цифрами. И это хорошо вписывается в наши 8-битные байты: две шестнадцатеричные цифры могут представлять каждое значение байта. Это также управляемая система для нашего мозга, действительно легко связать гекс с бинарным, когда вы привыкнете к нему.

Мы могли бы использовать систему base-256 при написании, но это было бы неудобно, потому что трудно придумать 256 легко набираемых, понятных и запоминающихся символов. Мы могли бы использовать систему base-17, но она не так аккуратно соответствует 8-значным двоичным числам. Таким образом, мы используем шестнадцатеричное, потому что это имеет огромное значение для нас.

Текст

Мы часто используем текст, поэтому нам выгодно предлагать стандартные способы представления символов, которые мы используем каждый день, в виде серии байтов. Это отображение символов в байты называется «кодировка символов» или «набор символов». Конечно, нам не хватает фактического согласования вещей, а также было разработано много разных таких сопоставлений независимо для многих разных потребностей, поэтому у нас есть много наборов символов, таких как ASCII, или ISO-8859-1, или JIS .

Кроме того, был изобретен юникод, чтобы попытаться определить стандарт, который сделал всех счастливыми, объединяя все наши различные кодировки символов, отсюда и название «юникод».

Но дело в том, что текст представлен сериями байтов, и то, что означает каждая серия байтов, определяется различными кодировками символов, и тот факт, что байты представляют текст вообще, основывается на предположении, что программа, читающая байты, понимает, что они должны представлять текст. Об ASCII удобно говорить, потому что каждый символ соответствует ровно одному байту, а также он действительно старый, очень простой, действительно широко использовался, и, несмотря на то, что он совершенно не подходит для мирового сообщества, все еще очень популярен и его легко обсуждать.

Семантика

Это, я убежден, самый запутанный момент для многих людей.

Байты - это просто байты. Они имеют по существу произвольные значения. Что на самом деле означают эти значения, определяется только контекстом и тем, что программа, читающая их, на самом деле делает с ними.

Например, если вспомнить, что байт может принимать 256 значений, значение 97 (двоичное 01100001, шестнадцатеричное 61) в конце дня может означать много разных вещей:

  • Если байт рассматривается как целочисленное значение, это число 97.
  • Если байт рассматривается как символ ASCII, это буква a .
  • Если байт рассматривается как машинная инструкция для процессоров, совместимых с Intel x86, это POPAилиPOPAD инструкция (не имеет значения, если вы не знаете, что это такое, это не главное).
  • Если байт представляет пиксель в изображении в градациях серого, вероятно, это оттенок серого .
  • Если байт является частью некоторых картографических данных для какой-либо игры, возможно, это дерево или забор или что-то еще.
  • И т.п.

Даже для числовых значений битовые комбинации могут иметь разное значение, например:

  • Иногда мы удовлетворены значениями 0-255. В других случаях мы хотим обрабатывать отрицательные числа, поэтому мы смещаем диапазон семантических значений от -128 до 127 и используем первый бит, чтобы указать, отрицателен он или нет. Или что угодно. Небо - это предел (хотя, как и кодировки символов, существует общепринятый стандартный набор правил и для целочисленных значений).
  • Иногда из-за различных обстоятельств мы даже кодируем целочисленные значения другими способами, например, BCD .
  • Иногда нам нужно представлять большие целые числа. Поэтому мы используем много байтов. Даже у этого есть варианты, см. «Endianness» .
  • Иногда нам нужно представлять десятичные числа. Здесь также много опций, см. Опцию с плавающей и фиксированной точкой .

Смысл всего этого в том, что байт - это просто байт, он ничего не значит, пока у вас нет контекста. Если программа записывает несколько байтов с некоторым предполагаемым значением, то только программа, которая читает их и интерпретирует их как имеющие такое же значение, сможет правильно понять это.

Соедини это все вместе

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

  • Ваш друг ссылается на идею о том, что вы сохраняете число как текстовое представление его значения в шестнадцатеричном формате . Например, значение 97 в шестнадцатеричном формате может быть 61. Это двухзначное число, содержащее символ «6», за которым следует «1». Закодировано как ASCII, которое будет двумя байтами: значение 54, за которым следует значение 49 (десятичное). Но это имеет смысл только тогда, когда, когда вы читаете эти байты назад, вы понимаете, что они представляют собой две шестнадцатеричные цифры в кодировке ASCII.
  • Вы также можете просто сохранить значение 97. Это только один байт. Это половина длины предыдущего варианта. Но, конечно, это имеет значение, только если, когда вы читаете этот байт назад, вы понимаете, что оно соответствует целочисленному значению .

Как правило, американские программисты, вероятно, выбрали бы второй вариант, но он действительно зависит от контекста. Например, в HTML-документе, предназначенном для чтения человеком, мы по-прежнему сохраняем такой атрибут, какwidth="97" . Конечно, здесь может потребоваться меньше места, чтобы использовать более узкое представление, но тогда было бы больно писать HTML. Так что это действительно зависит от контекста и варианта использования.

Я надеюсь, что по крайней мере что-то из этого имеет смысл.

0
sawdust

строка из шести десятичных чисел может храниться как 3 байта

Это звучит как BCD, двоично-десятичный код, представление в сравнении с числовыми символами ASCII (полный байт на цифру). Четыре бита используются для представления значений от 0 до 9. (Другие шесть значений не определены / недействительны.)
Значения BCD могут быть распакованы (одна цифра BCD на байт) или упакованы (две цифры BCD на байт).

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

Калькуляторы обычно используют представление BCD вместо двоичного. Длинная цепочка цифр на кредитных картах и ​​картах безопасности / доступа обычно кодируется в виде строки BCD на магнитной полосе или в передаваемом RF-пакете.
Цифровые компьютеры обычно используют двоичное представление для расчетов и хранения. CPU может иметь инструкции для выполнения арифметики BCD.