Разработка программы для перевода данных в разные системы счисления
Для создания программы был выбран язык Pascal, который не имеет стандартных функций (процедур) перевода в шестнадцатеричную систему счисления (16сс) и из 16сс в 10сс. Поэтому одной из главных задач является написать функции перевода 16 — >10 и 10→16. Также в Pascal нет стандартного типа для 16сс, поэтому будет использоваться строковой тип (srting). Перевод осуществляется посредством стандартного… Читать ещё >
Разработка программы для перевода данных в разные системы счисления (реферат, курсовая, диплом, контрольная)
Агентство по образованию РФ Рязанский государственный радиотехнический университет Кафедра САПР ВС Пояснительная записка по дисциплине «Информатика»
Тема «Разработка программы для перевода данных в разные системы счисления»
Выполнил студент 846 группы Чирков Антон Проверил Орехов В.В.
Рязань 2009
- Практическая и математическая постановки задачи
- Анализ существующих алгоритмов решения задачи
- Описание разрабатываемого алгоритма, его укрупненная схема
- Заключение
- Список литературы
Мы постоянно сталкиваемся с различными системами счисления в нашей повседневной жизни. Посмотрев на часы, мы даже не задумываемся, что имеем дело с шестидесятеричной системой счисления, с одной стороны, и двадцатичетырехричной — с другой. Задачи перевода в разные системы счисления особенно важны в компьютерной или IT сфере, так как большинство данных представляется не в привычной нам десятичной, а в двоичной, шестнадцатеричной и других системах счисления.
Практическая и математическая постановки задачи
Перед нами стоит цель составить программу для выполнения алгебраических действий с действительными числами без знака в шестнадцатеричной системе счисления (действия выполнять в десятичной системе счисления).
Для создания программы был выбран язык Pascal, который не имеет стандартных функций (процедур) перевода в шестнадцатеричную систему счисления (16сс) и из 16сс в 10сс. Поэтому одной из главных задач является написать функции перевода 16 — >10 и 10->16. Также в Pascal нет стандартного типа для 16сс, поэтому будет использоваться строковой тип (srting).
То есть для выполнения поставленной задачи необходимо:
· Считать строку, содержащую 2 аргумента и знак математического действия
· Разбить строку на 2 (извлечь аргументы), и сохранить знак действия
· Перевести каждый из аргументов в 10сс и выполнить действие, проанализировав знак математического действия.
· Полученный результат перевести в 16сс и вывести (на экран и/или в файл)
Анализ существующих алгоритмов решения задачи
Для перевода шестнадцатеричного числа в десятичное необходимо это число представить в виде суммы произведений степеней основания шестнадцатеричной системы счисления на соответствующие цифры в разрядах шестнадцатеричного числа.
система счисление программа алгоритм Например, требуется перевести шестнадцатеричное число 5A3 в десятичное. В этом числе 3 цифры. В соответствии с вышеуказанным правилом представим его в виде суммы степеней с основанием 16:
5A316=5· 162+10·161+3·160 =5· 256+10·16+3·1=1280+160+3=144310
Для перевода десятичного числа в шестнадцатеричное, необходимо целую часть числа целочисленно делить на основание степени 16, записав остатки в обратном порядке.
Например, переведем число 42210 в шестнадцатеричную систему счисления.
422: 16=26 (ост6)
26: 16=1 (ост10)
То есть получается 42210=1A616
Для перевода дробной части, необходимо умножать дробную часть на основание системы счисления (16), пока не получим дробную часть равную 0, или пока не достигнем необходимой точности.
Например, переведем 0,062510 в шестнадцатеричную систему счисления.
0, | ||
То есть мы получили, что 0,062510=0,116
Описание разрабатываемого алгоритма, его укрупненная схема
Считав строку, нам необходимо ее разбить на 2 аргумента и символ знака математического действия. Для этого мы «запускаем» цикл с параметром от 1 (начального символа) до длинны строки, и с помощью простого условия (if) ищем символ знака (+,-,*,/). Найдя этот символ, мы записываем его номер в переменную, если же мы не находим этот символ, то выдаем пользователю ошибку с просьбой ввести корректное выражение.
Имея порядковый номер знака математического действия, мы можем разбить строку на аргументы и «запомнить» знак.
Теперь у нас есть 2 аргумента в 16сс и знак математического действия. Для выполнения действия, нам необходимо перевести аргументы в 10сс.
Перевод осуществляется посредством стандартного алгоритма перевода в 10сс из любой системы счисления. Мы «нумеруем» разряды числа начиная от 0 (нулевого разряда), влево, прибавляя, а вправо — вычитая. И значение соответствующей цифры в разряде умножаем на основание системы счисления в степени порядкового номера разряда.
Возникает проблема. Мы функции передали строковой тип данных, и выполнение никаких математических действий с ней невозможно. Для начала, мы разбиваем строку на целую и дробную часть, с помощью цикла с параметром (от 1 до длинны строки), и ищем фиксированную точку (символ" ." или «,»). После чего разбиваем на 2 переменные, остаток и целую часть числа. Первая часть проблемы решена, второй проблемой является наличие в нашем числе буквенных символов, которые не получится обработать с помощью стандартной процедуры val. Для решения этой проблемы, мы воспользуемся таким алгоритмом:
· Переведем символ в верхнюю раскладку клавиатуры (UpCase)
· Считаем номер символа
· Вычтем из него номер символа «А»
Получили разность нашего символа и символа А. То есть если наш символ соответствует символу А, мы получим «0». Чтобы перевести этот символ корректно в 10сс, мы должны к этой разности прибавить 10.
Теперь у нас есть 2 числа в 10 системе счисления, осталось выполнить действие (предусмотрев, что разность чисел может быть отрицательной, и что пользователь может ввести делитель равный 0)
Мы получили искомый ответ в 10сс. Осталось только преобразовать его в 16сс. Для этого, мы преобразуем наше решение в строковой тип (стандартной процедурой str), и также разбиваем на остаток и целую часть числа. После чего, воспользовавшись правилом перевода числа из десятичной системы счисления в другую, переводим целую часть (посредством целочисленного деления с запоминанием остатка от деления), и дробную часть (посредством умножения на основания СС (16), и записи получившейся целой части).
Так выглядит приблизительный ход выполнения программы.
Текст программы:
{ЦЕЛЬ: выполнить все основные арифметические действия с действительными }
{числами с фиксированной запятой без знака в шеснадцатиричной }
{системе счисления (16сс), записав результат в файл }
{ПЕРЕМЕННЫЕ: allst — исходная строка, введенная пользователем, содержащая }
{математическое выражение с 16сс. gotst — результат выполнения операции }
{и исходная строка. n — переменная указателя меню }
{cl — булевая переменная с меткой выхода из программы }
{ПОДПРОГРАММЫ: StProc — процедура обработки первоначальной строки }
{stepen — функция возведения числа в положительную степень }
{minusstepen — функция возведения числа в отрицательную степень }
{_16to10 — функция перевода числа из 16сс в 10сс }
{_10to16 — функция перевода числа из 10сс в 16сс }
{Convd — функция преобразования символа }
{ВЫПОЛНИЛ студент группы 846 Чирков Антон }
{ПРОВЕРИЛ Орехов В. В. }
{ДАТА 11 мая 2009 года }
Program kursach;
var
n: integer;
allst, gotst: string;
cl: boolean;
result, data: text;
Procedure StProc (allst: string; var gotst: string);
var
i, zn1, zn2: integer;
mainzn: char;
st1, st2, dec: string;
{Функция положительной степени числа}
function stepen (x, n: integer): longint;
var
k: longint;
i: integer;
begin
k: =1;
for i: =1 to n do k: =k*x;
stepen: =k;
end;
{Функция отрицательной степени числа}
function minus_stepen (x, n: integer): real;
var
k: longint;
i: integer;
begin
k: =1;
for i: =1 to n do k: =k*x;
minus_stepen: =1/k;
end;
{Функчия перевода 16сс числа в 10сс}
function _16to10 (s: string): real;
var
m, n, z: longint;
i, num: integer;
ost: string;
drobch, res: real;
begin
drobch: =0;
m: =0;
num: =0;
{Проверяем, целое ли это число}
for i: =1 to length (s) do
if (s [i] ='. ') or (s [i] =',')
then
num: =i;
if num<>0
then
begin
ost: =copy (s, num+1,length (s) — num); {Создаем переменную с остатком}
delete (s, num, length (s) — num+1); {Выделяем целую часть}
{####### Переводим дробную часть #########}
n: =0;
for i: =1 to length (ost) do
begin
z: =0;
val (ost [i], n, z);
if z<>0 then n: =10+ord (UpCase (s [i])) — ord ('A');
drobch: =drobch+minus_stepen (16, i) *n;
end;
end;
n: =0;
{######## Переводим целую часть #########}
for i: =1 to length (s) do
begin
val (s [i], n, z);
if z<>0 then n: =10+ord (UpCase (s [i])) — ord ('A');
m: =m+stepen (16,length (s) — i) *n;
end;
_16to10: =m+drobch;
end;
{####### Функция _16to10 закончилась #####}
{####### Функция замены символа ##########}
function Convd (x: integer): char;
begin
if (x<10) then Convd: =chr (x+ord ('0'))
else
if (x<16)
then
Convd: =Chr (x-10+ord ('A'))
else
Convd: ='0';
end;
{####### Функция перевода 10 в 16 начало #}
function _10to16 (N: string): string;
var
s: string;
i, num, kon: integer;
chislo, ostatok: longint;
ostatok1: real;
err: longint;
ost: string;
begin
num: =0;
{Проверяем, целое ли это число}
for i: =1 to length (N) do
if (N [i] ='. ') or (N [i] =',')
then
num: =i;
if num<>0
then
begin
ost: =copy (N, num+1,length (N) — num); {Создаем переменную с остатком}
delete (N, num, length (N) — num+1); {Выделяем целую часть}
end;
Val (N, chislo, err);
Val (ost, ostatok, err);
ostatok1: =ostatok/ (stepen (10,length (ost)));
{Переводим целую часть}
s: ='';
repeat
s: =convd (chislo mod 16) +s;
chislo: =chislo div 16;
until chislo=0;
{Переводим дробную часть}
if num<>0
then
begin
s: =s+'. ';
kon: =0;
repeat
s: =s+convd (trunc (ostatok1*16));
ostatok1: =ostatok1- (trunc (ostatok1*16));
kon: =kon+1;
until (ostatok>0.1) or (kon=5);
end;
_10to16: =s;
end;
{######## Функция перевода 10 В 16 закончилась ##}
begin{Начала сомой процедуры обработки строк}
{разбиваем выражение на аргументы}
for i: =1 to length (allst) do
if ((allst [i] ='-') or (allst [i] ='+') or (allst [i] ='/') or (allst [i] ='*')) and (i<>1) and (allst [i-1] <>' (')
then
begin
st2: =copy (allst, i+1,length (allst) — i); {Создаем переменную со 2 аргументом}
st1: =copy (allst, 1, i-1);
mainzn: =allst [i];
end;
if mainzn=''
then
begin
st1: ='0';
st2: ='0';
WriteLn ('Введите корректное выражение');
end;
{Смотрим, небыло ли скобок у второго аргумента, и удаляем их}
for i: =1 to length (st2) do
if (st2 [i] =' (') or (st2 [i] =') ')
then
delete (st2, i, 1);
{Переводим числа в 10сс и выполняем действие}
dec: ='';
gotst: ='';
if mainzn='-'
then
begin
str ((_16to10 (st1)) — (_16to10 (st2)): 10: 3, dec);
{Проверяем знак результата}
for i: =1 to length (dec) do
if dec [i] ='-'
then
begin
delete (dec, 1, i);
gotst: ='-'
end;
gotst: =gotst+_10to16 (dec)
end;
if mainzn='+'
then
begin
str ((_16to10 (st1)) + (_16to10 (st2)): 10: 3, dec);
gotst: =gotst+_10to16 (dec)
end;
if mainzn='*'
then
begin
str ((_16to10 (st1)) * (_16to10 (st2)): 10: 3, dec);
gotst: =gotst+_10to16 (dec)
end;
if mainzn='/'
then
if (_16to10 (st2) =0) or (_16to10 (st2) <0.1)
then
gotst: ='error (на ноль делить нельзя!) '
else
begin
str ((zn1*_16to10 (st1)) / (zn2*_16to10 (st2)): 10: 3, dec);
gotst: =gotst+_10to16 (dec)
end;
WriteLn (allst,'=', gotst)
end;
{######## Процедура записи данных в файл #######}
Procedure resultPr (allst, gotst: string);
begin
gotst: =allst+'='+gotst;
Assign (result,'result. txt');
ReWrite (result);
Write (result, gotst);
Close (result);
WriteLn ('Данные успешно записаны в файл result. txt');
end;
{####### Процедура считывания переменной из файла}
Procedure dataPr (var allst: string);
begin
Assign (data,'data. txt');
Reset (data);
readLn (data, allst);
Close (data);
end;
begin {Начало программы}
cl: =false;
While not (cl) do
begin
WriteLn ('######################################################');
WriteLn ('## ##');
WriteLn ('## ЧТО БУДЕМ ДЕЛАТЬ? ##');
WriteLn ('## 1. Ввести выражение вручную ##');
WriteLn ('## 2. Прочитать выражение из файла data. txt ##');
WriteLn ('## 3. Записать выражение в файл result. txt ##');
WriteLn ('## 4. Выход из программы ##');
WriteLn ('## ##');
WriteLn ('######################################################');
WriteLn;
readLn (n);
case n of
1:
begin
WriteLn ('Введите выражение вида <�аргумент1><�действие><�аргумент2>');
WriteLn ('Например: F2A1. C7+C1.85');
readLn (allst);
StProc (allst, gotst);
readLn;
end;
2:
begin
dataPr (allst);
StProc (allst, gotst);
end;
3: resultPr (allst, gotst);
4: cl: =true;
end;
WriteLn; WriteLn; WriteLn; WriteLn; WriteLn; WriteLn; WriteLn;
end;
end.
Листинг с результатами машинного решения 1
######################################################
## ##
## ЧТО БУДЕМ ДЕЛАТЬ? ##
## 1. Ввести выражение вручную ##
## 2. Прочитать выражение из файла data. txt ##
## 3. Записать выражение в файл result. txt ##
## 4. Выход из программы ##
## ##
######################################################
Введите выражение вида <�аргумент1><�действие><�аргумент2>
Например: F2A1. C7+C1.85
5.5+7.6
5.5+7.6=C. B
Листинг с результатами машинного решения 2
######################################################
## ##
## ЧТО БУДЕМ ДЕЛАТЬ? ##
## 1. Ввести выражение вручную ##
## 2. Прочитать выражение из файла data. txt ##
## 3. Записать выражение в файл result. txt ##
## 4. Выход из программы ##
## ##
######################################################
Введите выражение вида <�аргумент1><�действие><�аргумент2>
Например: F2A1. C7+C1.85
A.3-F.3
A.3-F.3=-5.0
Листинг с результатами машинного решения 3
######################################################
## ##
## ЧТО БУДЕМ ДЕЛАТЬ? ##
## 1. Ввести выражение вручную ##
## 2. Прочитать выражение из файла data. txt ##
## 3. Записать выражение в файл result. txt ##
## 4. Выход из программы ##
## ##
######################################################
Введите выражение вида <�аргумент1><�действие><�аргумент2>
Например: F2A1. C7+C1.85
5f*10
5f*10=5F0.0
Листинг с результатами машинного решения 4
######################################################
## ##
## ЧТО БУДЕМ ДЕЛАТЬ? ##
## 1. Ввести выражение вручную ##
## 2. Прочитать выражение из файла data. txt ##
## 3. Записать выражение в файл result. txt ##
## 4. Выход из программы ##
## ##
######################################################
Введите выражение вида <�аргумент1><�действие><�аргумент2>
Например: F2A1. C7+C1.85
5FC.2B/0
5FC.2B/0=error (на ноль делить нельзя!)
Заключение
Цель была достигнута, посредством описанного выше алгоритма. Программа является универсальной и функциональной. Она способна
· Складывать шестнадцатеричные числа
· Вычитать шестнадцатеричные числа
· Умножать шестнадцатеричные числа
· Делить шестнадцатеричные числа
Все действия производятся с высокой степенью точности, и есть возможность автоматической записи результата выполнения действия в текстовый файл, легко читаемый любым текстовым редактором. Присутствует возможность считывания исходных данных как с клавиатуры, так и из файла, для выполнения дальнейших действий.
Для удобного использования программы было разработано меню, с пояснениями и примерами.
1. Москвитина О. А., Новичков В. С. Сборник примеров и задач по программированию: Учебное пособие. — М.: «Горячая линия телеком», 2005.
2. Новичков В. С. Лекции по курсу Городской Школы Программирования. — Рязань: 2007.
3. Орехов В. В. Лекции по курсу Информатики. — Рязань: 2009.
4. Информация с сайта wikipedia.org