Опубликован: 27.09.2006 | Уровень: для всех | Доступ: платный | ВУЗ: Московский государственный индустриальный университет
Лекция 4:

Особенности представления чисел в ЭВМ

< Лекция 3 || Лекция 4: 123 || Лекция 5 >
Аннотация: Представление информации в компьютере. Целые числа. Вещественные числа. Арифметические и побитовые операторы языка Java. Числа произвольной длины и точности.

Как уже отмечалось ранее, множествам целых \mathbb{Z} и действительных \mathbb{R} чисел в большинстве языков программирования соответствуют их машинные аналоги. В случае языка Java используемые в программах переменные величины и константы типов int и double принимают значения из множеств \mathbb{Z}_M и \mathbb{R}_M соответственно. В этом параграфе мы разберемся с тем, как именно устроены эти множества, и каковы последствия того, что программы оперируют не с настоящими числами, а с элементами указанных множеств. Однако сначала — некоторые напоминания об информации вообще и ее представлении в ЭВМ.

Представление информации в компьютере

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

Единицей измерения информации является бит (BInary digiT) — именно такое количество информации содержится в ответе на вопрос: нуль или один? Более крупными единицами измерения информации являются байт, килобайт (Kbyte), мегабайт (Mbyte), гигабайт (Gbyte) и терабайт (Tbyte). Один байт (byte) состоит из восьми бит, а каждая последующая величина больше предыдущей в 1024 раза.

Байта достаточно для хранения 256 различных значений, что позволяет размещать в нем любой из алфавитно-цифровых символов, если только мы можем ограничиться языками с небольшими алфавитами типа русского или английского. Первые 128 символов (занимающие семь младших бит) стандартизированы с помощью кодировки ASCII (American Standart Code for Information Interchange). Хуже обстоит дело с кодировками русского текста (символы русского алфавита расположены во второй половине таблицы из 256 символов) — их несколько, а наиболее распространенные из них сейчас две — Windows-1251 и KOI8-R.

Для кодирования всех возможных символов, используемых народами мира, одного байта мало — необходимо использовать два последовательных (стандарт Unicode). Именно так и поступают при хранении символьных ( char ) значений в языке Java.

Полезно знать, что 2^{10} = 1024 \approx 1000 = 10^3. Учитывая, что в книге среднего размера около 300000 букв, легко подсчитать, что, даже не используя никаких средств сжатия информации, на жестком диске современного персонального компьютера емкостью в 20 гигабайт можно разместить большую библиотеку из почти 70000 книг.

Целые числа

К целочисленным типам в языке Java относятся byte, short, int и long. Для хранения значений этих типов на любом компьютере отводится один, два, четыре и восемь байт соответственно. При этом применяется представление чисел в так называемом двоичном дополнительном коде.

Напомним, что используемая нами обычная система счисления является позиционной с основанием 10. Это значит, что в ней все натуральные числа представляются с помощью десяти цифр (от нуля до девяти включительно), а значение каждой из цифр числа зависит от позиции: самая правая цифра означает число единиц ( 10^0 ), вторая — десятков ( 10^1 ), третья — сотен ( 10^2 ) и так далее.

В p -ичной системе счисления все точно также, только число 10 в предыдущем абзаце нужно всюду заменить на p. Наряду с двоичной системой, в которой только две цифры (0 и 1), в информатике часто применяются восьмеричная с цифрами от нуля до 7 и шестнадцатеричная. В последнем случае в качестве цифр от десяти до пятнадцати используются буквы от A до F соответственно.

При записи положительных целых чисел в системе счисления с основанием p (на компьютере p=2 ) все их множество оказывается состоящим из элементов вида

d = \alpha_{n-1} p^{n-1} + \alpha_{n-2} p^{n-2} + \ldots + \alpha_0,
где величины \alpha_i для всех i из диапазона от n-1 до нуля — это цифры n -значного числа d в p -ичной системе счисления.

Перейдем теперь к вопросу представления отрицательных чисел. Для определенности рассмотрим тип byte, в котором любое число занимает ровно восемь бит. Из записи в двоичной системе счисления равенства (-1)+1=0 легко найти, какой вид должно иметь неизвестное нам пока двоичное представление xxxxxxxx числа -1:

xxxxxxxx + 00000001 = 00000000

Ясно, что на месте символов xxxxxxxx должно быть расположено число 11111111. Правильным результатом при этом, конечно, следовало бы считать 100000000, а не 00000000, но ведь мы имеем дело с типом byte и, так как результат обязан разместиться в байте, единица "исчезает".

Итак, число -1 должно кодироваться как 11111111. Дальнейшее уже совсем просто: для получения -2 нужно -1 уменьшить на единицу, что даст 11111110 ; число -3 представляется как 11111101 и т.д.

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

Легко видеть, что при этом самым маленьким отрицательным числом, которое принадлежит типу byte, является число -128 (двоичное представление 10000000 ), а самым большим — число 127 (представление 01111111 ). Все представимые числа (а их 256) в данном случае могут быть получены как пересечение двух множеств: множества \mathbb{Z} всех целых чисел и отрезка [-128, 127]. Интересным является следующее наблюдение: если число 01111111 увеличить на единицу, то получится 10000000, что означает следующее: 127 + 1 = -128\;!

Итак, множество элементов типа byte можно представлять себе в виде свернутого в кольцо отрезка [-128, 127]. Принципиально ничего не меняется и для типов short, int и long — увеличивается только длина отрезка, который вырезается из действительной прямой перед сворачиванием его в кольцо. Минимальные и максимальные представимые значения для каждого из этих типов в языке Java определены, как значения констант MIN_VALUE и MAX_VALUE в классах java.lang.Short, java.lang.Integer и java.lang.Long соответственно.

То, что для элементов множества \mathbb{Z}_M, являющегося машинным аналогом \mathbb{Z}, нарушено фундаментальное свойство целых чисел x
+ 1 > x, способно привести к различным невероятным на первый взгляд результатам, однако гораздо более странные вещи происходят при работе с вещественными числами.

< Лекция 3 || Лекция 4: 123 || Лекция 5 >
Анастасия Халудорова
Анастасия Халудорова
екатерина яковлева
екатерина яковлева
Ирина Тютрина
Ирина Тютрина
Россия, Усолье-Сибирское
Глеб Бочкарёв
Глеб Бочкарёв
Россия