Программирование. Память. Системы счисления

Компьютеры
Программирование. Системы счисленияЛюбая программа должна иметь возможность где-то хранить данные и удобно к ним обращаться. В общих словах – компьютеры имеют память, которая состоит из множества так называемых ячеек памяти.

Каждая ячейка имеет свой адрес. Чтобы в память записать значение или извлечь из памяти значение, достаточно обратиться к ячейке памяти по определенному адресу.



Опустим детали об организации памяти IBM-совместимого компьютера, так как мы будем заниматься языками высокого уровня, а не Ассемблером. Поэтому и нет смысла лезть в дебри, хотя там и нет ничего сложного. Теперь надо разобраться с системами счисления.

Позиционная система счисления, если простыми словами, то это некое множество знаков, значение которых зависит от положения в числе. Системы счисления могут быть и не позиционными с каким угодно основанием, например, факториальная система счисления и так далее, но это нам и не важно. Нам нужны только десятичная, двоичная и шестнадцатеричная системы счисления!

Так как у людей две руки, на каждой из которых по пять пальцев, то так и сложилось, что людям удобно использовать десятичную систему счисления, то есть систему с основанием 10. И множество знаков в этой системе такое: 0, 1, 2 , 3, 4, 5, 6, 7, 8, 9.

Теперь про позиции. Та же единица может стать десятком, сотней, тысячей – чем дальше она смещается от правого края, тем больше становится ее значение. Каждое смещение числа влево равносильно умножению данного числа на основание системы счисления!:
1 = 1
10 = 1*10
100 = 1*10*10
1000 = 1*10*10*10 и так далее.
Смещение вправо равносильно целочисленному делению на основание системы счисления. Все это справедливо для любой позиционной системы счисления.

В школах и в университетах на информатике зачем-то грузили слишком сложными методами перевода в двоичную систему. Говорилось про деление и остатки. Это долго и рутинно. Есть очень простой метод – просто выписать ряд чисел со степенями двойки, например:
128, 64, 32, 16, 8, 4, 2, 1

Теперь надо число, которое необходимо перевести в двоичную систему «разложить» так, чтобы оно же получилось из сумм чисел вышеприведенного ряда и под теми числами, которые суммируются, написать единицу, а под остальными записать нули, например:
129 = 128 + 1 = 10000001 Любая комбинация нулей и единиц для конкретного числа всегда единственная. 129 никак не удастся «соорудить» другой комбинацией нулей и единиц!
5 = 4+1 = 101;
15 = 8+4+2+1=1111;
34 = 32+2 = 100010.
Все проще простого.

А теперь – шестнадцатеричная система счисления!
Эта система состоит из 0,1,2,3,4,5,6,7,8,9,A,B,C,D, E,F – так как у нее – целых 16 цифр, поэтому нашу десятку пришлось заменить буквой «A», а 15, соответственно, буквой «F».

Переводить из десятичной в шестнадцатеричную тоже можно делением, но зачем?

Шестнадцатеричную систему счисления роднит с двоичной наличие тетрад – комбинаций четырехразрядных нулей и единиц. Каждое число от 0 до 15 если перевести в двоичную систему счисления, записывая строго четыре цифры, то и получим все тетрады, например: 0=0000, 1=0001, 2=0010, 3=0011… 14=1110, 15=1111.

Вот как переводят в шестнадцатеричную систему счисления:
25 = 24+1=16+8+1=0001 1001= 19;
245 = 240+5 = 128+64+32+16+4+1 = 1111 0101 = F5.
Если работа компьютера основана на двоичной логике, то 0 или 1 – это и есть один бит информации. Считается, что 0 – это логическая ложь, а единица или «не ноль» – логическая истина.

Байт – это 8 бит. И максимальное число в байте может быть вот какое:
128+64+32+16+8+4+2+1=255 или оно же в двоичном: 11111111 или в шестнадцатеричном: FF. При этом считается, что крайний левый бит считается старшим, а самый крайний – младшим. Биты нумеруются с нуля от младшего к старшему: младший бит – это бит с номером 0, старший бит – это бит с номером 7.

Но в байт можно записать и отрицательное число! Для этого надо бит с номером 7 выделить под знак, а на само число оставить 7 бит. В результате в байте можно записать диапазон чисел от -128 до +127 или от 10000000 до 01111111 или от 80 до 7F. Единица в седьмом бите означает, что число отрицательное!

Есть много способов перевода в двоичную систему отрицательных чисел, упоминается и дополнительный код и так далее, но можно и проще поступить:
Если максимальное число в одном байте= 255, то 256 уже никак не влезет в байт, но именно от 256 надо отнять отрицательное число и результат перевести в двоичную систему счисления и получим именно отрицательное число, например:
+5 = 00000101, а -5 = 256-5=251=11111011 или FB.
+127= 01111111=7F, а -127=256-127=129=10000001=81.

Точно также можно переводить и числа с большими значениями:
В 16 бит можно записать максимальное значение 65535. А если со знаком, то от -32768 до +32767.
Откуда эти диапазоны берутся: -128…+127, -32768…+32767?

Все очень просто. Если старший бит – это знаковый бит, то остальные биты и используются под число. -128 = 10000000. И это минимальное отрицательное число для 8 бит. Если к 128 прибавить 1, то получим 129. А 129 = 10000001. Если представить это, как число со знаком, то получим уже -127 или -128 + 1=-127. Вот отсюда и берутся эти диапазоны, в двоичном виде все выглядит так:
8 бит: 10000000…01111111 или 80…7F;
16 бит: 1000000000000000…0111111111111111 или 8000…7FFF;
32 бита: чтобы не городить длинные цепочки бит, напишу сразу в шестнадцатеричном представлении: 80000000…7FFFFFFF;
64 бита: 8000000000000000…7FFFFFFFFFFFFFFF и так далее.

Как видно, шестнадцатеричный код позволяет увидеть закономерность образования диапазонов знаковых чисел, когда в десятичном коде ничего этого не видно! И поэтому, именно в шестнадцатеричном виде удобно записывать адреса памяти – это намного нагляднее.

Еще вышеприведенное позволяет понять, почему, если к числу, например, -32768 прибавим -5, можем и не получить -32773! Попробуйте сами догадаться! Маленькая подсказка – в языках программирования есть типы данных, среди которых есть знаковые и беззнаковые. И, если переменную объявить, как целое число со знаком, то после операции сложения возникнет банальное переполнение, так как минимальное отрицательное может быть -32768. И в результате – неверный результат! Если такое произойдет в какой-нибудь финансовой задаче, то будет очень плохо! Это такая ошибка, которую сразу можно и не найти.

И напоследок – единицы измерения в мире компьютеров. Все то же самое, что и в мире людей, те же самые кило, мега, гига, тера, пета (пента) и так далее, только все умножается не на 1000, а на 1024. Например:
1 Килобайт вмещает в себя 1024 байта;
1 мегабайт вмещает в себя те же 1024, но уже килобайта;
1 гигабайт содержит в себе 1024 мегабайта;
1 терабайт равен 1024 гигабайтам;
1 петабайт (или его еще почему-то называют пентабайт) равен 1024 терабайтам и так далее…

К слову, было время, когда еще в ходу были винчестера аж на 20 мегабайт. И этого вполне хватало, так как более емких не было, поэтому и хватало. Так вот – в то время приставка «гига» пока еще редко употреблялась, так как оперативная память измерялась еще в килобайтах. 1 мегабайт оперативной памяти считалось еще более менее… Но все меняется. Когда размеры файлов начали измерять в гигабайтах, тогда и начали появляться винчестера, емкости которых начали мерить в терабайтах. Подозреваю, что и петабайты придут к обычным пользователям, но Майкрософт приложит усилия и выпустит софт, который будет измеряться в терабайтах.

0 комментариев

  • Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
    Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.