Разработка программы для перевода данных в разные системы счисления

Тип работы:
Реферат
Предмет:
Программирование


Узнать стоимость

Детальная информация о работе

Выдержка из работы

Агентство по образованию РФ

Рязанский государственный радиотехнический университет

Кафедра САПР ВС

Пояснительная записка

по дисциплине «Информатика»

Тема «Разработка программы для перевода данных в разные системы счисления»

Выполнил студент 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,

0625

1

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

Введите выражение вида < аргумент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

Введите выражение вида < аргумент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

Введите выражение вида < аргумент1><действие><аргумент2>

Например: F2A1. C7+C1. 85

5f*10

5f*10=5F0. 0

Листинг с результатами машинного решения 4

######################################################

## ##

## ЧТО БУДЕМ ДЕЛАТЬ? ##

## 1. Ввести выражение вручную ##

## 2. Прочитать выражение из файла data. txt ##

## 3. Записать выражение в файл result. txt ##

## 4. Выход из программы ##

## ##

######################################################

1

Введите выражение вида < аргумент1><действие><аргумент2>

Например: F2A1. C7+C1. 85

5FC. 2B/0

5FC. 2B/0=error (на ноль делить нельзя!)

Заключение

Цель была достигнута, посредством описанного выше алгоритма. Программа является универсальной и функциональной. Она способна

· Складывать шестнадцатеричные числа

· Вычитать шестнадцатеричные числа

· Умножать шестнадцатеричные числа

· Делить шестнадцатеричные числа

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

Для удобного использования программы было разработано меню, с пояснениями и примерами.

Список литературы

1. Москвитина О. А., Новичков В. С. Сборник примеров и задач по программированию: Учебное пособие. — М.: «Горячая линия телеком», 2005.

2. Новичков В. С. Лекции по курсу Городской Школы Программирования. — Рязань: 2007.

3. Орехов В. В. Лекции по курсу Информатики. — Рязань: 2009.

4. Информация с сайта wikipedia. org

ПоказатьСвернуть
Заполнить форму текущей работой