Upload
vladimir-parfinenko
View
1.555
Download
5
Embed Size (px)
DESCRIPTION
1. Двоичная система счисления, перевод чисел, битовое представление. 2. Шестнадцатеричная система счисления. 3. Хранение знака: знак в старшем бите (наивный способ). 4. Арифметика по модулю и двоичный дополнительный код. 5. Переполнение. 6. Двоично-десятичный код, Packed BCD. 7. Символы и кодировки: от ASCII к Unicode. 8. Строки, базовые способы их представления. 9. Операции со строками. 10. «Веревки» — альтернативный способ представления строк. 11. Сериализация и десериализация. Пример: сериализация массива чисел переменной длины. 12. Двойственность порядка байт: little-endian и big-endian.
Citation preview
ОСНОВЫ ПРОГРАММНОГО КОНСТРУИРОВАНИЯ
Лекция № 35 марта 2013 г.
ЧИСЛА В МАШИНЕ
• Нет единственного представления.
• Каждое представление имеет свои достоинства и недостатки.
• "123.45" (строка) – тоже вариант.
ДВОИЧНАЯ СИСТЕМА
• Быстрее всех.
• Память можно представить как:
• набор байтов, или 8-битных чисел (char).
• набор коротких слов, или16-битных чисел (short int).
• набор слов, или 32-битных чисел (int).
• набор длинных слов, или 64-битных чисел (long int).
ПЕРЕВОД 2 ⇔ 10
• Делим пополам, сохраняя остатки.
• 337=168*2+1; 168=84*2+0; 84=42*2+0; 42=21*2+0; 21=10*2+1; 10=5*2+0; 5=2*2+1; 2=1*2+0; 1=0*2+1.
• Записываем в обратном порядке: 1010100012=33710.
•Обратно: 1010100012=20+24+26+28=1+16+64+256=337.
В ПАМЯТИ
• Для представления числа 337 нужно как минимум 2 байта.
• 8 бит: 0..255
• 16 бит: 0..65535.
• 32 бита: 0..4294967295 (4,2 млрд.)
• 64 бита: 0..18446744073709551615 (≃1,8*1019).
0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 1
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
16-РИЧНАЯ СИСТЕМА
• Число в двоичной записи делится на тетрады (по 4 бита):
• 1010100012={0001}{0101}{0001}=15116.
• «Понятная» запись констант:
• 32 бита: диапазон чисел 0..FFFFFFFF16.
• 0xDEADBEEF, 0xCAFEBABE, …
КАК ХРАНИТЬ ЗНАК
•Отдельной памяти под знак нет, нужно втискивать его в те же 16 (8, 32, 64, …) бит.
• Кодируем знак: «плюс» ➯ 0, «минус» ➯ 1.
• Попробуем поместить знак в старший бит:
• +337 ➯ 0000 0001 0101 00012
• −337 ➯ 1000 0001 0101 00012
ПРОБЛЕМЫ СО ЗНАКОМ В СТАРШЕМ БИТЕ
• Простейшая арифметика (сложение, вычитание) отличается от беззнакового случая.
• Появляются случаи +0 и −0.
ДРУГОЙ ПОДХОД К ОТРИЦАТЕЛЬНЫМ ЧИСЛАМ
• Процессор выполняет операции сложения и вычитания по модулю, соответствующему размеру слова.
• В коротком слове: (FFFF16+1) mod 216=0.
• Забудем на секунду о модуле: X+1=0. Чему равно X?
ДВОИЧНЫЙ ДОПОЛНИТЕЛЬНЫЙ КОД
• −X ➯ 2N−X, где N – размер слова.(X+(−X)) mod 2N = 2N mod 2N = 0.(X−(−X)) mod 2N = (X+X+2N) mod 2N = 2X.
• Единица в старшем бите все-таки служит индикатором знака.Для N=8:
• 0000 00002 ➯ 0 (мин. положительное число).0111 11112 ➯ 127 (2N-1-1, макс. положительное число).1000 00002 ➯ −128 (−2N-1, мин. отрицательное число).1111 11112 ➯ −1 (макс. отрицательное число).
УМНОЖЕНИЕ И ДЕЛЕНИЕ
• Приходится учитывать знак. А вы как думали?
• Знаковое умножение и деление отличается от беззнакового.
ПЕРЕПОЛНЕНИЕ
• (−128)−1 = 1000 00002−1 = 0111 11112 = 127. Ого!
• 127+1 = 0111 11112+1 = 1000 00002 = −128. Ой!
НЕДОСТАТКИ ДВОИЧНОЙ СИСТЕМЫ
• Нормальные люди (не программисты) хотят видеть числа в 10-тичной системе (а не 2, 8, 16, …)
• Преобразование в 10-тичную систему требует памяти и вычислений (последовательное деление на 10 с остатком).
• Для встроенных систем (калькуляторы, холодильники) это может быть критично.
ВАРИАНТЫ?
• Хранить число прямо в строке (123456 ➯ "123456") слишком накладно по памяти.
• Промежуточный вариант: двоично-десятичное кодирование (BCD), т.е. битовое кодирование каждой десятичной цифры.
• Packed BCD: на каждую цифру тратится 4 бита (полубайт).
PACKED BCD
• 33710 ➯ {3}{3}{7} ➯ {0011}2{0011}2{0111}2=11001101112.
• BCD-представление числа 33710 аналогично двоичному представлению 33716! Для знака обычно выделяется младший полубайт:
• «+» ➯ C16=11002«−» ➯ D16=11012.
• Со знаком: 33710 ➯ 337С16= 0011 0011 0111 11002.
• В 32 битах можно представить числа ±9 999 999 (7 цифр+знак).
ОПЕРАЦИИ С PACKED BCD
• Можно складывать и вычитать битовые представления напрямую, если после этого выполнять коррекцию!
• 1116+1516=2616. Коррекция не требуется.
• 1116+1916=2A16. Поскольку был выход за границы 0..9, добавляем еще 6 к переполнившемуся разряду: 2A16+6=3016.
• Вычитание: A−B=A+(99....9)–B+1.
• Умножение – столбиком, деление – уголком.
СИМВОЛЫ
• Кодировка: соответствие символа коду (и наоборот).
• ASCII: основа всего.
• 32 управляющих символа.
• 96 информационных символов.
!"#$%&'()*+,—./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~_
УПРАВЛЯЮЩИЕ СИМВОЛЫ ASCII
• Null, 0x00, \0 – пустой символ.
• Bell, 0x07, \a – звуковой сигнал.
• Backspace, 0x08, \b – возврат на шаг.
• Character Tabulation, 0x09, \t – горизонтальная табуляция.
• Line Feed, 0x0A, \n – перевод строки.
• Line Tabulation, 0x0B, \v – вертикальная табуляция.
• Form Feed, 0x0C, \f – смена страницы.
• Carriage Return, 0x0D, \r – возврат каретки.
UNICODE
• Решение проблем с 8-битными кодировками.
• Композитные символы.
•Много кодов: 1 112 064.
• Требует либо много памяти (UTF-32), либо символы имеют переменную длину (UTF-8).
СТРОКИ
• Строка – массив символов, но может иметь переменную длину!
• Нужно как-то хранить длину, как?
ДЛИНА СТРОКИ
• Два стандартных приема:
• Хранение длины в начале строки (первые 1/2/4 байта).
• Специальный символ. В языке C этим символом является символ с кодом 0.
6 s t r i n g
s t r i n g \0
«ВЕРЕВКИ»
Основы
прог раммного конструирования
+
+
+
ОПЕРАЦИИ СО СТРОКАМИ
• Конкатенация
("abc" + "def" ➯ "abcdef").
• Вычисление длины.
• Выделение подстроки.
• Взятие символа по индексу i.
• Удаление/замена подстроки.
• Поиск символов.
• Поиск подстроки.
• Сравнение двух строк.
• Копирование.
• Разбиение на подстроки (например, на слова).
• Преобразование в число и наоборот.
СЕРИАЛИЗАЦИЯ
• Строка в широком смысле – последовательность байт известного размера.
• Сериализация: превращение любой структуры данных в строку (десериализация – восстановление структуры данных).
• Пример сериализации: массив целых чисел (int) переменной длины (N).
СЕРИАЛИЗАЦИЯ МАССИВА
• N+1 целых чисел: длина + значения самого массива.
• Big-endian и little-endian:
• 1234567816 ➯ 12 34 56 78 (big-endian, «от старшего к младшему»).
• 1234567816 ➯ 78 56 34 12 (little-endian, «от младшего к старшему»).
• Сериализация матрицы? Произвольного множества векторов?
КОНЕЦ ТРЕТЬЕЙ ЛЕКЦИИ