Минимальный объем памяти, выделяемый для хранения целого числа, один байт. Один байт – это восемь бит, тогда количество различных значений, которые можно уместить в этот объем, равняется 28=256.
Давайте поразмышляем, какие числа мы поместили бы в один байт памяти компьютера? Рассмотрим все возможные варианты ответов.
От 1 до 256. Удобен ли этот диапазон? Даже если нам никогда не понадобятся отрицательные числа, то нулевое значение нам нужно будет всегда.
От 0 до 255. Да такой вариант существует. Например, тип byte в Паскале использует этот формат хранения данных. Это представление называется беззнаковым, и целые числа в памяти компьютера хранятся в явном виде.
Значение
|
Представление
|
0
|
00000000
|
1
|
00000001
|
2
|
00000010
|
3
|
00000011
|
…
|
…
|
255
|
11111111
|
Таб.1
Операция сложения беззнаковых чисел происходит по стандартному алгоритму двоичной арифметики.
Сложим двоичные числа 65 и 42.
+01000001
|
|
+65
|
00101010
|
|
42
|
01101011
|
|
107
|
Очевиден следующий вопрос – что произойдет, если сумма двух 8-рарядных беззнаковых чисел превысит значение 255? Например, 167+198.
+10100111
|
|
+167
|
11000110
|
|
198
|
1 01101101
|
|
365
|
Произошел перенос значащего разряда за разрядную сетку. Следовательно, в разрядной сетке останется число 01101101, которое интерпретируется компьютером как 109. Если в программе, в которой происходит данное действие, контролируются подобные ситуации, то появится сообщение об ошибке. Если такая проверка не производится, то результат вычислений будет неправильным. Убедимся в этом.
Проведем компьютерный эксперимент. Если при компиляции программы у вас появляется ошибка Range check error, следовательно, компилятору дается директива отслеживать ошибочные ситуации. Чтобы убрать проверку, снимите опцию Options – Compiler… – Range checking.
var
a,b,c:byte;{Тип короткое целое без знака}
begin
a:=167;
b:=198;
c:=a+b;
writeln(c);
end.
Действительно, данная программа дает в результате 109.
Упражнение 11. Изучите ключи и директивы компилятора языка Паскаль. Найдите директиву компилятора, отключающую проверку выхода за разрядную сетку. Ответ: {$Q-}
Помимо однобайтового представления беззнаковых чисел (byte) в языке программирования Паскаль поддерживается двухбайтовый тип Word.
Знаковое представление целых чисел. Давайте придумаем способ, с помощью которого компьютер будет отличать положительные числа от отрицательных. Количество различных значений в байте памяти, как говорилось выше, 28=256. Получается 128 отрицательных значений и 128 положительных. Естественное предположение, что старший бит (под номером 7) отдается на обозначение знака. Пусть 1 в старшем разряде представляет отрицательное число, а 0 – число положительное. Тогда:
Значение
|
Представление
|
…
|
…
|
+2
|
00000010
|
+1
|
00000001
|
0
|
00000000
|
-1
|
10000001
|
-2
|
10000010
|
…
|
…
|
Таб.2
Получаем 127 положительных значений, 127 отрицательных значений и нулевое значение, то есть 255 значений. Потерялось одно значение 10000000.
Если цифровая часть положительных и отрицательных чисел всегда содержит абсолютную величину числа, то такой способ представления знаковых чисел называют прямым кодом. Обработка чисел, представленных в прямом коде:
-
требует отдельных операций над цифровой и знаковой частями,
-
требует альтернативного выполнения операций сложения и вычитания,
-
приводит к появлению двух представлений нуля: +0 (00000000) и -0 (10000000).
Наиболее сложной для реализации в данном представлении является операция вычитания.
С этой проблемой столкнулся еще Блез Паскаль в XVII веке при конструировании своей суммирующей машины. При реализации идеи автоматического переноса десятков Паскаля остановила определенная трудность: изобретенный им механизм переноса десятков работал при вращении счетных колес только в одном направлении, а это не позволяло производить вычитание вращением колес в противоположную сторону. Простой и остроумный выход из этого положения, найденный Паскалем, был настолько удачен, что используется в современных ЭВМ. Паскаль заменил вычитание сложением с дополнением вычитаемого.
Для 8-разрядной машины Паскаля, работавшей в десятичной системе счисления, дополнением числа А будет (100.000.000-А), поэтому операция вычитания В-А может быть заменено сложением В+(100.000.000-А)=100.000.000+(В-А). Получившееся число будет больше искомой разности на 100.000.000, но так как машина 8-разрядная, то единица в девятом разряде просто пропадает при переносе десятков из восьмого.
В компьютере происходит все то же, только в двоичной системе счисления.
Дополнением k-разрядного целого числа Z в двоичной системе счисления называется величина D(Z, k) = 2k – Z (1).
Данную формулу можно представить в ином виде: D(Z, k) = ((2k-1)-Z)+1. Число 2k-1, состоит из k наибольших в данной системе счисления цифр (в нашем случае одного байта – 11111111). Поэтому (2k-1)-Z можно получить путем дополнения до 1 каждой цифры числа Z и последующим прибавлением к последнему разряду 1.
Так как в двоичной системе счисления дополнением 1 является 0, а дополнением 0 является 1, построение D(Z, k) сводится к инверсии данного числа, т.е. замена нулей единицами и единиц нулями, и прибавлением 1 к последнему разряду. Другими словами, дополнение двоичного числа формируется в два этапа:
-
строится инвертированное представление исходного числа;
-
к инвертированному представлению прибавляется 1 по правилам двоичной арифметики.
Дополнительный код двоичных целых чисел строится по следующим правилам:
-
для Z≥0 дополнительный код совпадает с самим числом;
-
для Z<0 дополнительный код совпадает с дополнением модуля числа, т.е. D(|Z|, k).
Найдем диапазон знаковых целых чисел, занимающих один байт в памяти компьютера. Будем строить таблицу от нуля, затем представление +1 и -1, +2 и -2, и т.д.
Значение
|
Представление
|
+127
|
01111111
|
+126
|
01111110
|
…
|
…
|
+2
|
00000010
|
+1
|
00000001
|
0
|
00000000
|
-1
|
11111111
|
-2
|
11111110
|
…
|
…
|
-126
|
10000010
|
-127
|
10000001
|
-128
|
10000000
|
Таб.3
После построения такой таблицы становится очевидным, что ось симметрии диапазона проходит между 0 и -1. Следовательно, диапазон знаковых чисел, занимающих один байт в памяти компьютера – от -128 до +127. В языке программирования Паскаль этот тип данных обозначается служебным типом ShortInt (короткое целое).
Упражнение 12. Найдите диапазон знаковых и беззнаковых чисел для области памяти в 2 и 4 байта и поставьте им в соответствие типы данных языка программирования Паскаль. Ответ. Если число занимает два байта, то диапазоны следующие: 0...65535 (Word – слово), -32768...32767 (Integer – целое). Если число занимает четыре байта, то диапазоны следующие: 0..4294967295 (такого типа в Паскале нет), -2147483648.. 2147483647 (LongInt – длинное целое).
Анализируя полученную выше таблицу значений можно сделать вывод, что отрицательные двоичные числа содержат единичный бит в старшем разряде.
Число 65:
|
01000001
|
|
Инверсионные биты:
|
10111110
|
|
Плюс 1:
|
10111111
|
равно -65
|
Для определения абсолютного значения отрицательного двоичного числа в машинном представлении просто повторяют предыдущие операции: инвертируют все биты и прибавляют единицу.
Двоичное дополнение:
|
10111111
|
|
Инверсионные биты:
|
01000000
|
|
Плюс 1:
|
01000001
|
равно +65
|
Проверим, даст ли сумма +65 и -65 в результате 0:
+01000001
|
|
+65
|
10111111
|
|
-65
|
1 00000000
|
|
0
|
Все восемь бит имеют нулевое значение. Единичный бит, вынесенный за разрядную сетку влево, потерян.
Рассмотрим в общем случае сложение двух знаковых двоичных числа C=A+B
Старший бит числа A
|
Старший бит числа B
|
Старший бит числа С
|
Перенос единицы
из разрядной сетки
|
Комментарий
|
0
|
0
|
0
|
Нет
|
Сложение двух положительных чисел без переполнения. Результат корректен.
|
0
|
0
|
1
|
Нет
|
Переполнение при сложении двух положительных чисел. Результат некорректен.
|
1
|
1
|
1
|
Есть
|
Сложение двух отрицательных чисел без переполнения. Результат корректен.
|
1
|
1
|
0
|
Есть
|
Переполнение при сложении двух отрицательных чисел. Результат некорректен.
|
0
|
1
|
0
|
Есть
|
Сложение чисел с разными знаками; A>|B|.
Результат корректен.
|
0
|
1
|
1
|
Нет
|
Сложение чисел с разными знаками; A<|B|.
Результат корректен.
|
Таб.4
Рассмотрим все подобные случаи на примере.
Убедимся, что результат, получаемый компьютером при сложении положительного и отрицательного числа, получается корректным.
Вычтем 42 из 65. Найдем дополнительный код числа -42.
Число 42:
|
00101010
|
|
Инверсионные биты:
|
11010101
|
|
Плюс 1:
|
11010110
|
равно -42
|
Прибавим к +65 -42 по правилам машинной арифметики.
+01000001
|
|
+65
|
11010110
|
|
-42
|
1 00010111
|
|
23
|
Результат 23 является корректным.
Упражнение 13. Найти по правилам машинной арифметики сумму +42 и -65.
Решение.
Число 65:
|
01000001
|
|
Инверсионные биты:
|
10111110
|
|
Плюс 1:
|
10111111
|
равно -65
|
Прибавим к -65 +42 по правилам машинной арифметики.
+10111111
|
|
+-65
|
00101010
|
|
42
|
11101001
|
|
?
|
Убедимся, что результат корректный. Так как старший седьмой бит результата равен единице, то это отрицательное число в дополнительном коде. Найдем его абсолютное значение.
Число ?:
|
11101001
|
|
Инверсионные биты:
|
00010110
|
|
Плюс 1:
|
00010111
|
равно 23
|
Следовательно, в результате мы получили число -23, результат корректный.
Упражнение 14. Найти по правилам машинной арифметики сумму -42 и -65.
Решение. Сначала переводим оба числа в дополнительный код. Затем складываем эти числа.
+10111111
|
|
+-65
|
11010110
|
|
-42
|
1 10010101
|
|
?
|
При переходе единицы в знаковый разряд и за разрядную сетку не вызывает ошибки. Проверим полученный результат. Старший бит – 1, следовательно, полученное число отрицательное и представлено в дополнительном коде.
Число ?:
|
10010101
|
|
Инверсионные биты:
|
01101010
|
|
Плюс 1:
|
01101011
|
равно 107
|
Результат корректный.
Упражнение 15. Найдите результат сложения двух положительных знаковых целых числа: 102 и 54. Проведите вычисления, пользуясь алгоритмом машинной арифметики. Проведите компьютерный эксперимент. Напишите программу на Паскале, складывающую эти два числа. Сравните результаты, компьютерные и полученные вручную.
Решение.
+01100110
|
|
+102
|
00110110
|
|
54
|
10011100
|
|
?
|
Произошел перенос единичного разряда в знаковый разряд, выноса за разрядную сетку не было, следовательно, результат будет некорректным. Попробуем его перевести в десятичную систему счисления. Так как тип данных – знаковый, то единица в старшем разряде говорит нам о том, что число отрицательное и представлено в дополнительном коде.
Число ?:
|
10011100
|
|
Инверсионные биты:
|
01100011
|
|
Плюс 1:
|
01100100
|
равно 100
|
Следовательно, результат должен интерпретироваться как -100.
Попробуем провести компьютерный эксперимент.
{$Q-}
var
a,b,c:shortint;{Тип короткое целое со знаком}
begin
a:=102;
b:=54;
c:=a+b;
writeln(c);
end.
Действительно, данная программа дает в результате -100.
Упражнение 16. Найдите результат сложения двух отрицательных знаковых целых числа: -98 и -76. Проведите вычисления, пользуясь алгоритмом машинной арифметики. Проведите компьютерный эксперимент. Напишите программу на Паскале, складывающую эти два числа. Сравните результаты, компьютерные и полученные вручную. Ответ. 82.
Упражнение 17. Найдите описания всех операций Паскаля, определенных над целыми числами (целочисленное деление, поиск остатка от деления, сдвиг вправо и влево, побитные операции). Напишите программы, иллюстрирующие данные операции.
Упражнение 18. Подумайте, какие случаи не рассмотрены в таблице 4 и почему.
0>
Достарыңызбен бөлісу: |