- 1 -
2О Г Л А В Л Е Н И Е
2. Постановка задачи
3. Теоретическая основа решения задачи
4. Методологический подход
системы исчисления в другую
6. Текст программы с комментариями
7. Подробные разъяснения по программе
8. Как пользоваться программой
- 2 -
2I. В В Е Д Е Н И Е
Проблема перевода из одной системы исчисления в дру-
гую очень часто встречается при программировании. Осо-
бенно часто появляется такая проблема при программиро-
ячейки памяти, для получения двоичного или шестнадцати-
ричного эквивалентов десятеричного числа. Иногда встает
проблема увеличения скорости вычислений, и тогда прихо-
дит на помощь двоичная система исчисления. В этой
системе исчисления очень быстро производить операцию
умножения путем сдвига одного из операндов в двоичном
виде влево на такое число позиций в которой стоит еди-
ница во втором операнде.
Рассмотрим подробнее как это осуществляется. Пусть
нам надо умножить число 1101 на 101 (оба числа в двоич-
образом: она берет число 1101, и если первый элемент
второго множителя равен 1 то она заносит его в сумму.
чая тем самым 11010 и если второй элемент второго мно-
элемент второго множителя равен нулю то сумма не изме-
няется. В связи с этим, если второй множитель содержит
- 3 -
долго, т. к. машина проверяет каждую цифру второго мно-
жителя, в том числе и нули. Если же самому делать опе-
рацию умножения то нули можно пропустить и тогда умно-
жение сделается быстрее.
исчисления то здесь тоже большие возможности. Во-пер-
вых, некоторые стандартные процедуры Паскаля и Си тре-
буют задачи параметров в шестнадцатиричной системе, а
во-вторых, такая система исчисления очень удобна для
хранения информации, т. к. число в шестнадцатиричном ви-
де занимает меньше объема диска чем тоже число в деся-
теричном, а тем более в двоичном виде.
Таким образом мы убедились, что проблема перевода из
двоичной системы исчисления в десятеричную, из шестнад-
цатиричной в десятеричную и обратно очень актуальна.
Из введения стало понятно, что наиболее часто встре-
чающиеся системы исчисления это двоичная, шестнадцати-
ричная и десятеричная. Иногда встречается и восьмирич-
ная система исчисления, но это бывает так редко, что не
стоит на этом останавливаться. Итак, наша задача осу-
ществить перевод из двоичной системы исчисления в деся-
теричную и шестнадцатиричную, из десятеричной в двоич-
ную и шестнадцатиричную и из шестнадцатиричной в двоич-
системы исчисления.
- 4 -
2III. ТЕОРЕТИЧЕСКАЯ ОСНОВА РЕШЕНИЯ ЗАДАЧИ
Как же на практике осуществляется перевод из одной
Допустим нам нужно перевести число 567 десятеричной
системы в двоичную систему. Делается это следующим об-
разом: отыскивается максимальная степень двойки, чтобы
два в этой степени было меньше или равно исходному
числу. В нашем случае это 9, т. к. 2^9=512, а 2^10=1024
что больше нашего начального числа. Таким образом мы
получили число разрядов результата. Оно равно 9+1=10.
Значит результат будет иметь вид 1ххххххххх, где вместо
х может стоять 1 или 0. Найдем вторую цифру результата.
т. е. результат уже примет вид 10хххххххх. Рассмотрим
> 55, значит и восьмой разряд
будет нулем. Т. к. 2^6=64 то седьмой разряд равен нулю.
Таким образом мы получили четыре старших разряда и
число примет вид 1000хххххх. Вычисляем 2^5=32 и видим,
что 32 < 55, значит шестой разряд равен 1 (результат
10001ххххх), остаток 55-32=23. 2^4=16 < 23 - пятый раз-
ряд 1 => 100011хххх. Остаток 23-16=7. 2^3=8 > 7 =>
< 7 => 10001101хх, остаток 3. 2^1=2 <
3 => 100011011х, остаток 1. 2^0=1 = 1 => 1000110111. Мы
получили конечный результат.
- 5 -
Теперь попробуем перевести тоже число 567, но уже в
шестнадцатиричную систему. Подход примерно такой же.
Определим максимальный разряд. Т. к. 16^2=256 < 567, а
16^3=4096 > 567, то максимальный разряд 2+1=3. Опреде-
лим число, которое будет стоять в третьем разряде.
Ищется максимальный множитель в пределах от 1 до 15,
чтобы текущая степень шестнадцати умноженная на этот
множитель была меньше или равнялась исходному числу (а
2, т. к. 256*2=512 < 567, а 256*3=768 > 567. Значит
старший разряд нашего результата будет равен 22 0, и ре-
зультат примет вид 2хх, где вместо х могут стоять любые
цифры или буквы из ниже перечисленных:
567-2*16^2=55. Определим что будет стоять во втором
< 55, а 4*16^1=64 > 55, то
во втором разряде будет стоять цифра 23 0. Оста-
ток=55-3*16^1=7. Определяем первый разряд: т. к. 16^0=1
то цифра первого разряда равна остатку, т. е. 27 0. Таким
образом мы получили число 2237 0, но уже в шестнадцатирич-
ной системе исчисления.
Операция перевода из десятеричной системы выглядит
гораздо проще. Рассмотрим ее на примере перевода из
шестнадцатиричной системы в десятеричную.
Допустим нам нужно перевести число 24A3F 0в десятерич-
ную систему. Берем старший (4 ый) разряд и возводим 16
в степень 4-1=3, получаем 16^3=4096. Полученный резуль-
тат умножаем на значение четвертого разряда, т. е. 4.
- 6 -
Получается 4096*4=16384. Этот результат мы заносим в
сумму. Переходим к следующему разряду: 16^2=256. 256
нужно умножить на значение третьего разряда т. е. A. Как
известно в шестнадцатиричной системе исчисления буквы
от A до F символизируют числа от 10 до 15 ( A=10, B=11,
C=12, D=13, E=14, F=15). Умножив 256 на 10 получим 2560
и этот результат добавляем к сумме, в которой у нас по-
ка было 16384. В сумму у нас получилось 18944. Перехо-
получим 18992. И последний разряд: 15*16^0=15. Конечная
сумма равна 219007 0. Мы получили результат в десятеричной
системе исчисления.
2IV. МЕТОДОЛОГИЧЕСКИЙ ПОДХОД
пень, затем в обоих случаях сравниваем остаток с числом
возведенным в степень разряда. Единственная разница
заключается в том, что при переводе в двоичную систему
основанием степени служит двойка, а при переводе в
шестнадцатиричную систему основанием служит число шест-
надцать. Возникает вопрос: а нельзя ли объединить оба
этих перевода в одну процедуру, в которую в качестве
параметров передавать основание степени? При более под-
заметить, что сравнивая остаток со степенью двойки мы
- 7 -
рассматриваем не просто степень числа шестнадцати, а
нет разницы между тем, сравнивать степень с остатком
или с остатком умноженным на единицу. Таким образом вы-
яснилось, что перевод из десятеричной системы исчисле-
ния в двоичную и в шестнадцатиричную можно осуществлять
давать основание степени, т. е. основание конечной
системы исчисления.
Чтобы не усложнять программу и не делать множество
операторов условного перехода в зависимости от того, к
ввод этого числа осуществляется единым блоком, и исход-
ное число в результате выполнения этого блока записыва-
ется в виде строковой переменной и передается на обра-
ботку следующему блоку. Второй блок поступившую в него
строку символов обрабатывает таким образом, что на вы-
ходе этого блока получается числовое значение в десяте-
заключительный блок преобразует это числовое значение в
строку символов, которая будет содержать результат в
системе исчисления, которая требовалась.
В результате такого подхода к решению задачи алго-
ритм значительно упрощается, т. к. в нем нет ветвлений.
- 10 -
2VII. ПОДРОБНЫЕ РАЗЪЯСНЕНИЯ ПО ПРОГРАММЕ
Программа начинается стандартной строкой:
Program Perevod;
Далее следует описательная часть программы. Она
- Uses: указывает какие внешние TPU файлы будет
- Const: описывает используемые в программе констан-
ты. S - массив констант строк символов состоящих из пя-
будут использоваться для составления меню.
- Var: описывает переменные.
Longint - целочисленный тип, значение которого может
изменяться от -2147483648 до 2147483647 и занимает в
памяти 32 бита.
Integer - целочисленный тип, может принимать значе-
ние от -32768 до 32767 и занимает объем памяти в 16
бит.
Char - символьный тип, может принимать значение лю-
бого символа.
Byte - целочисленный тип, может принимать значения
Set of '0'.. 'F' - тип множество, элементы которого
могут быть любые символы находящиеся в промежутке от
'0' до 'F'.
Array [1.. 255] of Char - массив символов размером в
- 11 -
255 знаков.
String - строка символов переменной длины (длина мо-
Далее в программе идет описание процедуры Zast. Эта
процедура выводит на экран в столбик пункты меню, в ко-
торых указывается из какой и в какую систему исчисления
пользователь хочет перевести число. Структура процедуры
линейная. Она состоит из нескольких операторов:
Window (1,1,80,24) - отводит окно доступное для вы-
вода.
ClrScr - очищает экран.
TextColor (15) - устанавливает цвет последующего вы-
GoToXY (x,y) - переводит курсор в строку с номером y
ражение указанное в скобках.
Далее в программе следует функция возведения в сте-
пень. Она будет использоваться в дальнейшей программе
несколько раз для непосредственного перевода из одной
системы исчисления в другую, поэтому пришлось оформить
ее как функцию, чтобы не использовать каждый раз опера-
ции с логарифмом и экспонентой. Возведение в степень в
ваться.
Продолжим рассмотрение программы. После функции воз-
- 12 -
части основной программы Begin.
Переменной Y присваивается значение 1 - начальное
Далее идет вызов процедуры Zast, в результате выпол-
нения которой на экран выводится список возможных ком-
бинаций переводов.
После выполнения процедуры Zast следует оператор ор-
ганизации цикла с пост-условием Repeat. Внутри этого
раммы.
Внутри него последовательно идет установка цвета на
малиновый, перемещение курсора в позицию 13,2 и вывод
символа метки текущего положения курсора в меню ( 2> 0 ).
Далее идет оператор ожидания ввода клавиши ReadKey.
переменной Klav. Затем идет стирание метки текущей по-
После этого идет блок условных операторов If, кото-
рые обрабатывают нажатую клавишу и выполняют определен-
ные действия в соответствии с нажатой клавишей.
Первый оператор If обрабатывает ситуацию, если была
нажата клавиша "ВВЕРХ". В результате его выполнения
значение переменной Y уменьшается на единицу, а если
Аналогично действует второй условный оператор, только
он обрабатывает клавишу "ВНИЗ".
Третий условный оператор принимает значение True
если была нажата клавиша ESC (выход). В этом случае пе-
- 13 -
ременной Y присваивается значение 7, а переменной Klav
волизируют выход из внешнего цикла с пост-условием, а
значит и выход из программы.
Четвертый условный оператор обрабатывает клавишу
ВВОД, но при условии, что Y<7, т. е. курсор в меню не
подведен к последней строке со значением выхода из
программы. Если значение выражения этого условного опе-
ратора примет значение True, то начинается выполнение
посредственно перевод из одной системы исчисления в
другую.
Сначала очищается экран. Затем малиновым цветом в
первой строке выводится из какой и в какую систему
исчисления программа будет переводить числа. После это-
го, в нижней строке зеленым цветом выводится фраза "ESC
- ВЫХОД В МЕНЮ". Затем устанавливается цвет вывода на
экран белый и выделяется окно для вывода исключающее
первую и последнюю строки экрана. Переменной Stroka
(переменная указывает строку положения курсора) присва-
ивается значение 2.
После этих подготовительных процессов оператор Case
в зависимости от того из какой и в какую систему
исходного числа) и Kon (основание конечной системы
исчисления).
- 14 -
Далее в программе следует оператор цикла с
пост-условием Repeat, внутри которого осуществляется
ввод исходного числа. Сначала идет ожидание нажатия
клавиши запишется в переменную Klav. Стандартная функ-
ция UpCase переводит символ из нижнего регистра в верх-
ний. Условный оператор If определяет, является ли нажа-
тая клавиша допустимой, и если это так, то переменная
Kol (количество символов во введенном числе) увеличива-
ется на единицу, значение клавиши записывается в массив
A (массив символов с исходным числом) и введенная кла-
виша отображается на экране.
Следующий условный оператор определяет, не была ли
нажата клавиша ЗАБОЙ. В этом случае Kol уменьшается на
единицу, курсор перемещается на одну позицию влево и
стирается последний введенный символ.
Оператор Until осуществляет выход из цикла с
пост-условием в том случае, если была нажата клавиша
ВВОД или клавиша ESC.
Далее следует условный оператор, который обрабатыва-
означает, что исходное число введено и пользователь хо-
чет получить результат, и необходимо приступить к не-
посредственному переводу.
Внутри этого условного оператора выполняется цикл от
1 до Kol (количество символов в исходном числе). Внутри
этого цикла условным оператором If определяется в за-
нейшего умножения, а затем переменная Promeg увеличива-
ется на число равное произведению полученного числового
степени Kol-1. В результате выполнения этого цикла мы
из исходного числа в виде набора символов получили его
значение в десятеричной системе исчисления. Таким обра-
зом половину перевода мы осуществили. Теперь нам нужно
Далее следует обнуление переменной I, а после этого
циклом с пост-условием определяется максимальный поря-
док результата (см. п. III. Теоретические основы решения
задачи).
После того как мы определили этот порядок и записали
лучения необходимого результата:
- переменной Help присваивается числовое значение
Jтого элемента в исходном результате;
- условным оператором If из этого значения получает
символ, который будет стоять в результате;
которая будет содержать результат;
- вычисляется остаток, который записывается в пере-
менную Promeg.
Все эти действия были описаны в теоретической части
настоящего реферата, а их практическое осуществление не
требует никакого труда.
После выполнения этих операций, программа переходит
- 16 -
ний символ искомого результата. Как только результат
получен, он выводится на экран оператором WriteLn.
После этого следует переход на начало цикла с
виша ESC. Если все же была нажата клавиша ESC то выпол-
нение программы передается основному циклу с
пост-условием который включает в себя выбор в меню.
Условие выхода из этого цикла - это нажатие клавиши
"ESC - ВЫХОД В
DOS".
Если это условие выполнилось, то осуществляется очи-
2VIII. КАК ПОЛЬЗОВАТЬСЯ ПРОГРАММОЙ
меню возможных переводов:
- 17 -
_____________________________________________________
> Перевод из десятеричного кода в двоичный.
Перевод из двоичного кода в десятеричный.
Перевод из двоичного кода в шестнадцатиричный.
Перевод из шестнадцатиричного кода в двоичный.
_____________________________________________________
Слева от первой строки стоит метка выбора. Клавишами
ВВЕРХ и ВНИЗ можно перемещать метку по меню. После того
как метка подведена к нужной строке нажимается клавиша
ВВОД. Если Вы хотите из главного меню выйти из прог-
раммы, то это можно сделать двумя способами: нажать
Если Вы нажали ВВОД на одной из верхних строк меню
то на экране появляется следующая картина:
_____________________________________________________
Перевод из десятеричного кода в двоичный.
? 32 = 100000
? 33 = 100001
? 26 = 11010
? 500 = 111110100
? 3 = 11
? 34_
ESC - ВЫХОД В МЕНЮ
_____________________________________________________
Однако вместо верхней строки может стоять любая из
шести строк указанных в меню, в зависимости от того,
стоя на какой строке меню Вы нажали ВВОД.
В этом состоянии можно вводить исходное число, при-
чем программа будет сама определять, допустимый символ
только клавиши '1' или '0', в противном случае програм-
ма нажатую клавишу не проигнорирует.
- 19 -
После того как Вы ввели исходное число, нужно нажать
клавишу ВВОД, после чего напротив исходного числа через
знак равно появится эквивалент исходного числа, но уже
в нужной системе исчисления.
Если Вы ошиблись при вводе исходного числа, то можно
нажать клавишу ЗАБОЙ, и последний введенный символ сот-
рется.
Чтобы завершить выполнение программы или осуществить
перевод из другой системы исчисления, нужно нажать кла-
вишу ESC (о чем указано в нижней строке экрана). В этом
продолжить перевод, то опять клавишами ВВЕРХ и ВНИЗ
подведите курсор к нужной строке меню и нажмите ВВОД.
Если же Вы хотите завершить выполнение программы, то
- 8 -
Program Perevod;
Uses Crt;
Const P1='Перевод из '; { константы для начального меню }
s:array [1.. 7] of string[50]=(p1+'десятеричного кода в двоичный. ',
p1+'двоичного кода в десятеричный. ',
p1+'шестнадцатиричного кода в десятеричный. ',
p1+'двоичного кода в шестнадцатиричный. ',
p1+'шестнадцатиричного кода в двоичный. ',
' ESC - ВЫХОД В DOS');
Var Promeg,Chast:Longint;
Klav:Char;
i,Stroka,Isx,Kon,y,Kol,Help:Byte;
a: Array [1.. 255] of Char;
begin
Window(1,1,80,24); { выделить окно 80х24 }
TextColor(15); { установить цвет - белый }
FOR I:=1 TO 7 do begin { цикл по строкам }
GoToXY (15,I*2); Write (s[i]); { формирование меню }
end;
end { zast }; { конец процедуры меню }
var c: Byte;
begin
For c:=1 to st do Res:=Res*chis;
Stepen:=Res; { присвоение функции значения }
Begin { НАЧАЛО ОСНОВНОЙ ПРОГРАММЫ }
Zast; { вывести меню }
Repeat { цикл для перемещения в меню }
klav:=ReadKey; { считывание клавиши в klav }
GoToXY (13,y*2); Write(' '); { стирание старой метки текущей строки }
> 1 then y:=y-1 else y:= 7; { если клавиша ВВЕРХ }
if Ord(Klav)=80 then if y < 7 then y:=y+1 else y:= 1; { если клавиша ВНИЗ }
if Ord(Klav)=27 then begin y:=7; klav:=Chr(13) end; { если клавиша ESC }
if (Ord(Klav)=13) and (y<7) then begin { если клавиша ВВОД не на выходе }
TextCOLOR (10); GoToXY (31,24); Write ('ESC - ВЫХОД В МЕНЮ'); { вывести клавишу для выхода }
TextColor(15); { поменять цвет - белый }
Window(1,2,80,23); { установить окно со 2 по 23 строки }
Stroka:=2; { текущая строка }
- 9 -
Case y of { определение клавиш которые можно будет нажимать }
1,3 : begin { если перевод из десятиричного кода }
Keys:=['0'.. '9']; { возможные клавиши }
If y=1 Then Kon:=2 else Kon:=16; { присвоение системы исчисления результата }
end;
If y=2 Then Kon:=10 else Kon:=16; { присвоение системы исчисления результата }
end;
4,6 : begin
isx:=16;
keys:=['0'.. '9','A'.. 'F']; { определение клавиш которые можно будет нажимать }
if y=4 then kon:=10 else kon:=2; { присвоение системы исчисления результата }
end;
end;
Repeat { основной цикл для перевода }
Write('? '); Promeg:=0; Kol:=0; Otv:=''; { подготовительные действия }
Repeat { цикл для ввода числа }
klav:=ReadKey; { чтение клавиши }
if UpCase(Klav) in Keys then begin { если клавиша допустимая }
kol:=kol+1; { количество символов в исходном числе }
a[kol]:=UpCase(Klav); { запоминание введенного символа }
Write (a[kol]); { вывод нажатого символа }
end;
if (Ord(Klav)=8) and (Kol>0) then begin { если клавиша ЗАБОЙ }
kol:=kol-1;
GoToXY(WhereX-1,WhereY);
ClrEol;
end;
Until (Ord(klav)=13) or (Ord(klav)=27); { пока не нажата ВВОД или ESC }
if Ord(klav)=13 then begin { если клавиша ВВОД - начало обработки результата }
for i:=1 to kol do begin { перевода введенного числа в десятеричную систему}
if a[i]<'A' then Znach:=Ord(a[i])-48
else Znach:=Ord(a[i])-55;
promeg:=promeg+Znach*Stepen(isx,kol-i);
end;
i:=0;
i:=i+1;
Chast:=Trunc(Promeg/Stepen(Kon,i));
Until Chast<Kon;
For j:=i downto 0 do begin { перевод в нужную систему исчисления }
Help:=Trunc(Promeg/Stepen(Kon,j));
If Help>9 Then Pom:=Chr(55+Help)
Otv:=Otv+Pom;
Promeg:=Promeg-Help*Stepen(Kon,j);
end;
WriteLn(' = ',Otv); { вывод результата }
end; { конец обработки результата }
Until Ord(Klav)=27; { если нажата ESC то выход в основное меню }
Zast; { вывод заставки }
end;
Until (Ord(Klav)=13) and (y=7); { если в меню нажали ESC или ВВОД на выходе }
ClrScr { очистить экран }
end.
|