Файл: Разработка модуля для выполнения операций с натуральными числами в шестнадцатеричной системе счисления (Теоретические основы систем счисления ).pdf
Добавлен: 29.02.2024
Просмотров: 47
Скачиваний: 0
СОДЕРЖАНИЕ
1 Теоретические основы систем счисления
1.1 Общие сведения о системах счисления
1.3 Перевод натурального q-ичного числа в десятичную систему счисления
1.5 Арифметические операции над натуральными числами в позиционных системах счисления
2.1 Выбор языка программирования и среды разработки
2.2 Постановка задачи на программирование
2.2 Постановка задачи на программирование
Разрабатываемый программный продукт должен представлять собой законченное приложение с понятным консольным интерфейсом, созданное на языке высокого уровня Паскаль (в среде разработки PascalABC.NET).
Назначение составляемой программы – выполнение операций с натуральными числами в шестнадцатеричной системе счисления.
Создаваемое приложение-калькулятор должно функционировать следующим образом:
- Запрашивать у пользователя номер действия (операции), которое потребуется выполнить (если введен несуществующий номер операции, программа должна завершать работу, выводя перед этим сообщение об ошибке на экран, иначе – продолжать работу):
- сложение шестнадцатеричных чисел (1);
- умножение шестнадцатеричных чисел (2);
- вычитание шестнадцатеричных чисел (3);
- деление шестнадцатеричных чисел (4);
- перевод шестнадцатеричного числа в двоичную, восьмеричную и десятичную системы счисления (5);
- перевод в шестнадцатеричную из двоичной, восьмеричной или десятичной системы счисления (6);
- Осуществлять ввод данных для выбранной операции, то есть натуральных шестнадцатеричных чисел и при преобразовании в шестнадцатеричное число основания системы счисления (2, 8 или 10), из которой осуществляется перевод, с клавиатуры.
- Производить проверку входных данных, если введены некорректные значения, программа должна запрашивать повторный ввод, выводя перед этим соответствующее сообщение на экран. Также для исключения ошибок при дальнейших вычислениях из чисел должны удаляться незначащие нули слева, и не должно иметь значения, какие латинские буквы введены в качестве шестнадцатеричных цифр – большие или малые.
- Выполнять выбранное действие (причем, при выполнении деления должна производиться проверка – не введен ли в качестве делителя ноль, при вычитании – должен выводиться знак разности – «+» или «−»).
- Выводить результат на экран.
Также программа должна выводить все необходимые пояснения и подсказки, быть законченной и удобной для использования.
2.3 Листинг программного кода
Для каждой операции с натуральными шестнадцатеричными числами, а также для проверки правильности введенных чисел написаны отдельные подпрограммы-функции, все они вынесены в отдельный модуль modul16.pcu.
Ниже представлены листинги основной программы и вышеупомянутого модуля modul16.
Блок-схемы алгоритмов основной программы и подпрограмм, выполненные в MS Visio, приведены в Приложении А.
2.3.1 Текст основной программы
program ss16;
uses crt, modul16;
procedure vvod(var s: string; e: string; ss: byte);//ввод ss-ного числа
begin
repeat//цикл для ввода и проверки ss-ного числа
write(e);
readln(s);
writeln;
if (proverk(s, ss) = false) then writeln('Число введено неверно, повторите ввод!');
until proverk(s, ss);//пока условие ложно цикл работает
while ((s[1] = '0') and (length(s) > 1)) do delete(s, 1, 1);//удаляем незначащие нули слева числа
end;
var
s, s1: string;//введенное число
n: char;//цифра из меню, которую выбирает пользователь
o: integer;//основание сс
i: integer;//код ошибки процедуры val
begin
clrscr;//процедура очистки экрана из модуля crt
textcolor(10);//далее вывод салатовым цветом
writeln('ПРОГРАММА ДЛЯ ВЫПОЛНЕНИЯ ОПЕРАЦИЙ С НАТУРАЛЬНЫМИ 16РИЧНЫМИ ЧИСЛАМИ');
textcolor(14);//далее вывод желтым цветом
writeln(#10, 'Выберите действие:');//#10 - переход на следующую строку
textcolor(15);//далее вывод белым цветом
writeln(' * 1 - сложение 16ричных чисел');
writeln(' * 2 - умножение 16ричных чисел');
writeln(' * 3 - вычитание 16ричных чисел');
writeln(' * 4 - деление 16ричных чисел');
writeln(' * 5 - перевод из 16ричной в 2ную, 8ричную и 10ную системы cчисления');
writeln(' * 6 - перевод в 16ричную из 2ной, 8ричной или 10ной системы cчисления');
writeln(' * любая другая цифра или буква - выход из программы.');
write('Ваш выбор - ? ');
readln(n);
writeln;//пропуск строки
textcolor(14);//далее вывод желтым цветом
if n in ['1'..'7'] then writeln('Выполнение выбранной операции:')//если введен существующий номер действия
else writeln('Операции с таким номером не существует!');//если введен несуществующий номер действия
textcolor(15);//далее вывод белым цветом
case n of
'1'://если выбран пункт 1
begin
vvod(s, 'Введите первое 16ричное слагаемое (должно состоять из цифр от 0 до 9 и латинскихбукв от A до F): ', 16);
vvod(s1, 'Введите второе 16ричное слагаемое (должно состоять из цифр от 0 до 9 и латинскихбукв от A до F): ', 16);
writeln('Сумма данных 16ричных чисел: ', sum(s, s1));
end;
'2': // если выбран пункт 2
begin
vvod(s, 'Введите первый 16ричный множитель (должно состоять из цифр от 0 до 9 и латинскихбукв от A до F): ', 16);
vvod(s1, 'Введите второй 16ричный множитель (должно состоять из цифр от 0 до 9 и латинскихбукв от A до F): ', 16);
writeln('Произведение данных 16ричных чисел: ', proiz(s, s1));
end;
'3':// если выбран пункт 3
begin
vvod(s, 'Введите 16ричное уменьшаемое (должно состоять из цифр от 0 до 9 и латинскихбукв от A до F): ', 16);
vvod(s1, 'Введите 16ричное вычитаемое (должно состоять из цифр от 0 до 9 и латинских букв от A до F): ', 16);
writeln('Разность данных 16ричных чисел: ', raz(s, s1));
end;
'4':// если выбран пункт 4
begin
vvod(s, 'Введите 16ричное делимое (должно состоять из цифр от 0 до 9 и латинских букв от A до F): ', 16);
vvod(s1, 'Введите 16ричный делитель (должно состоять из цифр от 0 до 9 и латинских букв отA до F): ', 16);
writeln('Частное от деления данных 16ричных чисел: ', del(s, s1));
if (del(s, s1) <> 'На ноль делить нельзя!') and (del(s, s1) <> '0') then writeln('Остаток от деления данных 16ричных чисел: ', raz(s, proiz(s1, del(s, s1))));
end;
'5':// если выбран пункт 5
begin
vvod(s, 'Введите 16ричное число для перевода в 2ную, 8ричную и 10ную сс (должно состоятьиз цифр от 0 до 9 и латинских букв от A до F): ', 16);
writeln('Число в 2ной системе счисления: ', iz16v2(s));
writeln('Число в 8ной системе счисления: ', iz2v8(iz16v2(s)));
writeln('Число в 10ной системе счисления: ', iz16v10(s));
end;
'6':// если выбран пункт 6
begin
repeat//ввод и проверка основания сс
write('Введите основание системы счисления (2, 8 или 10): ');
readln(s);
val(s, o, i);//преобразуем строку в число
if not ((o = 2) or (o = 8) or (o = 10)) then writeln('Основание системы счисления введено неверно, повторите ввод!');
writeln;
until (o = 2) or (o = 8) or (o = 10);
vvod(s, 'Введите число для перевода (должно состоять из цифр от 0 до ' + chr(47 + o) + '): ', o);
write('Число в 16ричной системе счисления: ');
if o = 2 then writeln(iz2v16(s))
else if o = 8 then writeln(iz2v16(iz8v2(s)))
else writeln(iz10v16(s));
end;
end;
writeln;
textcolor(14);//далее вывод желтым цветом
writeln('-----------------------------------------------------');
textcolor(15);//далее вывод белым цветом
writeln;
writeln('Для завершения программы нажмите любую клавишу...');
readkey;//пауза перед закрытием консоли
end.
2.3.2 Текст модуля modul16
unit modul16;
interface//интерфейсная часть модуля
function proverk(chislo: string; ss: integer): boolean;
function iz16v2(c16: string): string;
function iz16v10(c16: string): string;
function iz2v8(c2: string): string;
function iz2v16(c2: string): string;
function iz8v2(c8: string): string;
function iz10v16(c10: string): string;
function sum(c1, c2: string): string;
function proiz(c1, c2: string): string;
function raz(c1, c2: string): string;
function del(c1, c2: string): string;
implementation//исполняемая часть модуля
function zam(s: char): integer;//замена 16ричной цифры на 10ное число
begin
case s of//цифра заменяется соответствующей 10ной
'a', 'A': zam := 10;
'b', 'B': zam := 11;
'c', 'C': zam := 12;
'd', 'D': zam := 13;
'e', 'E': zam := 14;
'f', 'F': zam := 15;
else zam := ord(s) - 48;
end;
end;
function proverk(chislo: string; ss: integer): boolean;//проверяет введено ли 2ное, 8ричное, 10ное или 16ричное число правильно
var
c: set of char = ['0'..'9'];//символы, из которых состоит 10ричное число
flag: boolean;//логическая переменная равна true, только если число введено правильно
i: integer;//номер цифры в числе
begin
flag := true;
//далее формирование алфавита сс
if ss <> 16 then for i := ss to 9 do c := c - [chr(48 + i)]//цикл запускается, если число 2ное или 8ричное
else c := c + ['a'..'f', 'A'..'F'];//если число 16ричное
//далее проверка правильно ли введено число
for i := 1 to length(chislo) do if not (chislo[i] in c) then flag := false;//если символ числа имеет недопустимое значение
if length(chislo) = 0 then flag := false;//если число не введено
proverk := flag;
end;
function iz16v2(c16: string): string;//перевод из 16ричной сс в 2ную
var
i: integer;//номер цифры в числе
n: string;//строка, в которую записывается 2ное число
begin
n := '';//очистка строки
for i := 1 to length(c16) do//проходим все цифры 16ричного числа
case c16[i] of//цифра заменяется соответствующей 2ной тетрадой
'0': n := n + '0000';
'1': n := n + '0001';
'2': n := n + '0010';
'3': n := n + '0011';
'4': n := n + '0100';
'5': n := n + '0101';
'6': n := n + '0110';
'7': n := n + '0111';
'8': n := n + '1000';
'9': n := n + '1001';
'a', 'A': n := n + '1010';
'b', 'B': n := n + '1011';
'c', 'C': n := n + '1100';
'd', 'D': n := n + '1101';
'e', 'E': n := n + '1110';
'f', 'F': n := n + '1111';
end;
while ((n[1] = '0') and (length(n) > 1)) do delete(n, 1, 1);//удаляем незначащие нули слева
iz16v2 := n;
end;
function iz16v10(c16: string): string;//перевод из 16ричной сс в 10ную
var
i, j: integer;//счетчики циклов
n, m: uint64;//искомое 10ное число
s: string;
begin
n := 0;//обнуляем 10ное число
for i := 1 to length(c16) do//проходим все цифры 16ричного числа
begin
m := 1;
for j := 1 to length(c16) - i do m := m * 16;//возведение 16 в степень
if (18446744073709551615 - zam(c16[i]) * m) <= n then//проверка не выходит ли полученное число за границы uint64
begin
iz16v10 := 'слишком большое число для перевода';
exit;
end;
n := n + zam(c16[i]) * m;//сложение цифры, умноженных на 16 в степени разряда
end;
str(n, s);//перевод числа в строку
iz16v10 := s;
end;
function iz2v8(c2: string): string;//перевод из 2ной сс в 8ричную
var
i: integer;//номер цифры в числе
n: string;//строка, в которую записывается 8ричное число
n1: string;//строка, в которую записывается триада
j: integer;//8ричная цифра
a: array [0..7] of string = ('000', '001', '010', '011', '100', '101', '110', '111');//все триады
begin
n := '';//очистка строки
while length(c2) mod 3 <> 0 do insert('0', c2, 1);//вставляем незначащие нули слева, для разбивки по 3 цифры (триады)
i := 1;//номер первой цифры 2ного числа
repeat//замена 2ных триад на 8ричные цифры
n1 := copy(c2, i, 3);//запись триады
for j := 0 to 7 do if a[j] = n1 then n := n + j;
i := i + 3;
n1 := '';//очистка строки
until i >= length(c2);//пока число не закончится
while ((n[1] = '0') and (length(n) > 1)) do delete(n, 1, 1);//удаляем незначащие нули слева
iz2v8 := n;
end;
function iz2v16(c2: string): string;//перевод из 2ной сс в 16ричную
var
i: integer;//номер цифры в числе
n: string;//строка, в которую записывается 16ричное число
n1: string;//строка, в которую записывается триада
j: integer;//16ричная цифра в 10сс
a: array [0..15] of string = ('0000', '0001', '0010', '0011', '0100', '0101', '0110', '0111', '1000', '1001', '1010', '1011', '1100', '1101', '1110', '1111');//все тетрады
begin
n := '';//очистка строки
while length(c2) mod 4 <> 0 do insert('0', c2, 1);//вставляем незначащие нули слева, для разбивки по 4 цифры (тетрады)
i := 1;//номер первой цифры 2ного числа
repeat//замена 2ных тетрад на 16ричные цифры
n1 := copy(c2, i, 4);//запись тетрады
for j := 0 to 9 do if a[j] = n1 then n := n + j;
for j := 10 to 15 do if a[j] = n1 then n := n + chr(j + 55);
i := i + 4;
n1 := '';//очистка строки
until i >= length(c2);//пока число не закончится
while ((n[1] = '0') and (length(n) > 1)) do delete(n, 1, 1);//удаляем незначащие нули слева
iz2v16 := n;
end;
function iz8v2(c8: string): string;//перевод из 8ричной сс в 2ную
var
i: integer;//номер цифры в числе
n: string;//строка, в которую записывается 2ное число
begin
n := '';//очистка строки
for i := 1 to length(c8) do//проходим все цифры 16ричного числа
case c8[i] of//цифра заменяется соответствующей 2ной тетрадой
'0': n := n + '000';
'1': n := n + '001';
'2': n := n + '010';
'3': n := n + '011';
'4': n := n + '100';
'5': n := n + '101';
'6': n := n + '110';
'7': n := n + '111';
end;
while ((n[1] = '0') and (length(n) > 1)) do delete(n, 1, 1);//удаляем незначащие нули слева
iz8v2 := n;
end;
function iz10v16(c10: string): string;//перевод из 10ной сс в 16ричную
var
i: integer;//код ошибки процедуры val
n: string;//искомое 16ное число
c: uint64;//10ное число
q: string[16] = '0123456789ABCDEF';//цифры 16ной сс
begin
val(c10, c, i);//преобразуем строку в число
if i <> 0 then//проверка не выходит ли полученное число за границы uint64
begin
iz10v16 := 'слишком большое число для перевода';
exit;
end;
n := '';//очищаем строку
if c = 0 then n := '0';//если введен 0
while c > 0 do
begin
n := q[c mod 16 + 1] + n;//остаток от деления на 16 записываем в начало строки
c := c div 16;//сокращаем
end;
iz10v16 := n;
end;
function sum(c1, c2: string): string;//сумма 16ричных чисел
var
i: integer;//номер цифры в строке (числе)
s: string;//строка, в которую записывается сумма
r: array[1..100] of integer;//массив с суммами цифр
q: string[16] = '0123456789ABCDEF';//цифры в 16ной сс
begin
while length(c1) > length(c2) do insert('0', c2, 1);//вставляем незначащие нули слева пока числа не будут одинаковой длины
while length(c1) < length(c2) do insert('0', c1, 1);//вставляем незначащие нули слева пока числа не будут одинаковой длины
for i := 1 to length(c1) do r[i + 1] := zam(c1[i]) + zam(c2[i]);//сложение без переноса разряда
r[1] := 0;
for i := length(c1) + 1 downto 2 do//переносы разрядов
if r[i] > 15 then//если переполнение в текущей цифре суммы