Завдання
Варіант № 2
Написати програму системний калькулятор
(Переклад цілих чисел з однієї системи числення в другу)
Метою даної роботи є написання програми, що реалізує калькулятор.
Потрібно розробити алгоритм вирішення задачі (представити його у вигляді блок-схеми) і реалізувати в середовищі програмування Delphi.
Програма була розроблена на комп'ютері наступної конфігурації:
процесор AMD Athlon64 X2 4800+;
4Гб ОЗУ;
Відеокарта з 1 Гб відеопам'яті;
Windows 7 Ulimate;
Анотація
Програма «Калькулятор» була розроблена як один з варіантів програми для виконання переводу чисел з одної системи числення в іншу, а також для поглиблення знань по створенню Windows-додатків, середовища програмування Delphi 7. Програма є вікно (мал.1) з розташованими на ньому полями для вводу даних необхідних для роботи.
(Мал.1)
Список використаних змінних
У програмі «Калькулятор» були використані стандартні елементи Delphi 7. Її просту структуру відображає мал.2.
(Мал.2)
Елементи з приставко “ed” це поля для вводу даних. Інші елементи Label є текстовими помітками на графічній формі. Елемент btnTransform це кнопка яка запускає перерахування.
Алгоритм
Опис алгоритму
Програма повинна мати:
поле для введення чисел;
відповідні кнопки.
Алгоритм у вигляді блок-схеми
Блок-схема процедури, що виконується при створенні форми, зображена на малюнку 3.
(Мал.3)
Виконана програма на мові Object Pascal в середовищі Delphi 7
Інтерфейс програми
Інтерфейс програми (Form1) зображений на рисунку 4.
Малюнок 4 – Інтерфейс Form1
Текст програми та модулів форм
unit uMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Math;
type
TfrmMain = class(TForm)
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
edSrcBase: TEdit;
edSrcNum: TEdit;
edTrgPrecision: TEdit;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
btnTransform: TButton;
edTrgBase: TEdit;
edTrgNum: TEdit;
procedure btnTransformClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmMain: TfrmMain;
implementation
uses StrUtils;
{$R*.dfm}
//Переведем число в "букво-цифру"
function IntToDigit(aNum : Byte) : String;
const
SelfName : String = 'IntToDigit.';
begin
case aNum of
0..9 : Result := IntToStr(aNum);
10 : Result := 'A';
11 : Result := 'B';
12 : Result := 'C';
13 : Result := 'D';
14 : Result := 'E';
15 : Result := 'F';
//если добавить сюда еще пару строчек тогда можно увеличить систему счисления
else
RaiseException.Create(SelfName+ ' Ошибка при попытке преобразования числа в знак!');
end;
end;
//Переведем "букво-цифру" в число
function DigitToInt(aDigit : AnsiChar; aBase : Byte) : Byte;
const
SelfName : String = 'DigitToInt.';
begin
ifaBase< 2then
//На всякий случай сделаем проверку если кто-то введет "одноичную" систему :)
RaiseException.Create(SelfName+ ' Основание системы счисления должно быть >= 2!')
;
case aDigit of
'0'..'9' : Result := StrToInt(aDigit);
'A', 'a' : Result := 10;
'B', 'b' : Result := 11;
'C', 'c' : Result := 12;
'D', 'd' : Result := 13;
'E', 'e' : Result := 14;
'F', 'f' : Result := 15;
//если добавить сюда еще пару строчек тогда можно увеличить систему счисления
else
//если был введен символ которого нет в "переводе"
RaiseException.Create(SelfName+ ' Неизвестный символ в представлении числа!');
end;
ifResult>aBase- 1then
//если в выбранной начальной системе счисления нет такой цифры
RaiseException.Create(SelfName+ ' В данной системе счисления нет такой цифры!')
;
end;
//По записи числа в системе счисления с онованием aBase, определяет само это число.
function XcimalStrToNumber(aStrXcimal : String; aBase : Byte) : Extended;
const
SelfName : String = 'XcimalStrToNumber.';
var
i, j : Integer;
StrInt : String;
StrFrac : String;
Pos1 : Integer;
IntPart : Extended;
FracPart : Extended;
begin
if Length(aStrXcimal) = 0 then
Raise Exception.Create(SelfName + ' Не задано число!')
;
//Ищем десятичную точку или запятую
Pos1 :=Pos(',',aStrXcimal);
if Pos1 = 0 then
Pos1 := Pos('.', aStrXcimal)
;
ifPos1 = 0thenbegin
//Число состоит только из целой части числа
StrInt := aStrXcimal;
StrFrac := '';
end else begin
//Число имеет целую и дробную части числа
StrInt := LeftStr(aStrXcimal, Pos1 - 1);
StrFrac := Copy(aStrXcimal, Pos1 + 1, Length(aStrXcimal) - Pos1);
end;
//Определяем значение целой части числа.
IntPart := 0;
for i := 1 to Length(StrInt) do begin
j := Length(StrInt) - i;
IntPart := IntPart + DigitToInt(StrInt[i], aBase) * Power(aBase, j);
end;
//Определяем значение дробной части числа.
FracPart := 0;
for i := 1 to Length(StrFrac) do begin
j := Length(StrFrac) - i;
FracPart := FracPart + DigitToInt(StrFrac[i], aBase) * Power(aBase, j);
end;
FracPart := FracPart / Power(aBase, Length(StrFrac));
//Получаем число, которое соответствует записи aStrXcimal
//в исходной системе счисления
Result:=IntPart+FracPart;
end;
//Преобразует запись числа в исходной системе счисления в запись
//этого же числа в конечной системе счисления.
//Преобразование производится с точностью до указанной пользователем
function XcimalStrToYcimalStr (
aSrcBase : Byte;
aSrcNumStr : String;
aTrgBase : Byte;
aTrgPrecision : Byte
) : String;
var
SrcNum : Extended;
IntPart : Int64;
FracPart : Extended;
StrInt : String;
StrFrac : String;
//Счетчег
i : Integer;
TempNum : Extended;
begin
SrcNum := XcimalStrToNumber(aSrcNumStr, aSrcBase);
//Получаем целую и дробную части числа.
IntPart := Trunc(SrcNum);
FracPart := Frac(SrcNum);
//Переводим целую часть.
StrInt:= '';
repeat
StrInt := IntToDigit(IntPart mod aTrgBase) + StrInt;
IntPart := IntPart div aTrgBase;
until IntPart = 0;
// Если дробной части числа нету, тогда решение завершено
if FracPart = 0 then begin
Result := StrInt;
exit;
end;
//Переводим дробную часть учитывая указанную пользователем
StrFrac := '';
for i := 1 to aTrgPrecision do begin
TempNum := FracPart * aTrgBase;
StrFrac := StrFrac + IntToDigit(Trunc(TempNum));
FracPart:=Frac(TempNum);
//Если пользователь указал 0 в "числе знаков после запятой" тогда выходим
if FracPart = 0 then Break;
end;
Result := StrInt + ',' + StrFrac;
end;
procedure TfrmMain.btnTransformClick(Sender: TObject);
begin
edTrgNum.Text := XcimalStrToYcimalStr(
StrToInt(edSrcBase.Text),
edSrcNum.Text,
StrToInt(edTrgBase.Text),
StrToInt(edTrgPrecision.Text)
);
end;
end.