В предыдущем выпуске я рассказал, что данные в памяти компьютера хранятся исключительно как числа, но мы назначаем им разный смысл: число 65 можно понимать как количество предметов, или как букву "A", или как интенсивность синего цвета и т.д. То есть эти с виду одинаковые числа имеют различный тип.
Существует, фактически, три основных типа данных: число, символ и строка. Чтобы расставить все точки над i, я опишу каждый из них подробнее, и в этом выпуске речь будет про семейство числовых типов.
Я уже неоднократно показывал, как числа записываются в память. Но есть один нюанс: все эти числа были целыми. Я постоянно писал 5, 20, 65, но никогда не писал 5.2, 3.33, 0.001 и т.п.
Как хранят дробные числа? Да так же, как и всё остальное. У каждого дробного числа есть его целочисленное представление. Я не буду углубляться в подробности, потому что это скучноватая математика. Ну если нам придется самим это придумывать, то самый наивный и топорный способ – умножить число на 1000, например, 5.2 * 1000 = 5200. Можете в качестве разминки сказать, чем плох этот способ, или придумать свои варианты, или погуглить, как оно на самом деле.
Второй нюанс – это числа со знаком и без. Как хранятся отрицательные числа, например -5? Здесь поступили хитро. Для того, чтобы задать знак "-", используют самый старший бит числа (0 – нет знака, 1 – есть знак). Одновременно с этим получается, что максимальное число, которое можно записать со знаком, в два раза меньше, чем число, которое можно записать без знака.
Смотрите: в байте есть 8 бит. Если хранить там числа, у которых точно не бывает знака, то есть строго положительные, можно использовать все 8 бит. Максимальное число в одном байте это 11111111, или 255.
Если хранить там числа, у которых может быть или не быть знак, то один бит нужно потратить на хранение знака. А само число можно записать только в оставшиеся 7 бит. А это уже 1111111, или 127. Но зато мы можем хранить числа от -128 до 127.
Интересный факт: отрицательные числа чаще всего хранятся в специальном (дополнительном) формате, который использует инверсию бит (это когда нули меняются на единицы и наоборот). Сделано это для того, чтобы математические операции с любыми числами, и с положительными, и с отрицательными, работали корректно. Но здесь надо вдаваться в двоичную математику, поэтому оставим на потом. Пока неважно.
Кроме того, все числа бывают "короткие" и "длинные":
Можно работать с самыми короткими числами длиной 8 бит, или 1 байт (0..255, или -128..127),
длиной 16 бит, или 2 байта (0..65535, или -32768..32767),
длиной 32 бита, или 4 байта (0..4294967295, или -2147483648..2147483647),
длиной 64 бита, или 8 байт (это безумно много)
Операции чтения-записи чисел длиной в несколько байт поддерживаются компьютером на аппаратном уровне, поэтому здесь не нужно прилагать никаких усилий. Однако 8-битный компьютер, естественно, не сможет работать с 16 битами, а 32-битный не сможет работать с 64 битами. Но 64-битный сможет работать и с 8, и с 16, и с 32 битами.
Наконец, есть еще один простейший вариант числа: логический. Это число, которое принимает только значения "истина" и "ложь". Оно нужно для хранения состояний и условий. Например, вам не важно, сколько у вас книг, а важно только их наличие.
Сначала вы ставите вопрос: у меня есть книги? Если есть, то ответом будет "истина". Если нет, то ответом будет "ложь". Для хранения типа "истина/ложь" ничего особенного не требуется. Это обычное целое число, для "истины" мы пишем 1, а для "лжи" 0, вот и всё. Значение такого числа помещается в один бит. Но мы же помним, что в память можно записать минимум один байт, поэтому на такое число потратится целый байт. Однако, можно взять от 2 до 8 разных логических чисел, математически объединить их в 1 байт и записать его. Тогда получится, что в 1 байте мы храним сразу несколько логических чисел, и каждый бит в этом байте - это одно число. Но этим мы займемся, когда будем проходить битовые операции.
В следующем выпуске я расскажу про символьный тип и строку, ну а дальше можно будет заняться уже языками программирования.