Pascal: Калькулятор для перевода из одной системы счисления в другую
В прошлом году я писал программу для перевода из любой системы в любую систему счисления на си. Теперь потребовалось на Pascal.Функций стало больше. Некоторые пришлось просто копировать с других сайтов (да простят меня авторы)
К сожалению, точность вычислений здесь меньше, чем была на си — всего один знак после запятой точен.
Ограничение во FreePascal: числа в 16-ричной системе можно вводить только большими буквами. Нет функции UpperCase, писать было лень :)
Исходный код (FreePascal):
program test;
uses crt, math, strings;
var
s, s1,s2 : string; // число для перевода
base_in : integer; // Основание входной системы счисления
base_out : integer; // Основание выходной системы счисления
function CheckDotCount(s: string): boolean; // Проверка количества точек в числе
var
count, i : integer;
begin
count := 0;
for i := 1 to Length(s) do
if (s[i] = '.') then inc(count);
if (count > 1) then CheckDotCount := false
else CheckDotCount := true;
end;
function IntToHex(ds: byte): string;
const
b: string = '0123456789ABCDEF';
begin
if (b[(ds shr 4) + 1] = '0') then
IntToHex:= b[(ds and $F) + 1]
else IntToHex:= b[(ds shr 4) + 1] + b[(ds and $F) + 1];
end;
function HexToInt(s: string): Longword;
var
b: Byte;
c: Char;
r: Longword;
begin
r := 0;
//s := UpperCase(s);
for b := 1 to Length(s) do
begin
r := r * 16;
c := s[b];
case c of
'0'..'9': Inc(r, Ord(c) - Ord('0'));
'A'..'F': Inc(r, Ord(c) - Ord('A') + 10);
end;
end;
HexToInt := r;
end;
function checkSS(base : integer; s : string): boolean;
var
i: integer;
flag : boolean;
begin
flag := true;
for i := 1 to Length(s) do
begin
if (HexToInt(s[i]) >= base) then flag := false;
end;
if ((base > 16) or (base < 2)) then flag := false;
checkSS := flag;
end;
function checkSSR (base : integer):boolean;
begin
if ((base > 16) or (base < 2)) then checkSSR := false
else
checkSSR := true;
end;
function getStringBeforeDot(s:string): string;
//pos : integer;
begin
if (Pos('.',s) = 0) then getStringBeforeDot := s
else getStringBeforeDot := Copy(s, 1,Pos('.',s)-1);
end;
function getStringAfterDot(s: string):string;
begin
if (Pos('.',s) = 0) then getStringAfterDot := ''
else
getStringAfterDot := copy(s,Pos('.',s)+1,Length(s));
end;
procedure IntConverter(s:string; base_in : integer; base_out : integer);
var
n1,N,i,r1 : integer;
d1 : array [0..255] of integer;
begin
n1 := Length(s);
N := 0;
for i := 1 to n1 do
begin
N:= N*base_in+HexToInt(s[i]);
end;
if (N = 0) then write ('0')
else
begin
r1 := 0;
while (N <> 0) do
begin
d1[r1] := N mod base_out;
N := N div base_out;
inc(r1);
end;
for i:=r1-1 downto 0 do
write(IntToHex(d1[i]));
end;
end;
procedure DotConverter(s:string; base_in : integer; base_out : integer);
var
n2 , i, k2: longint;
Nf : double;
begin
n2 := Length(s);
if (n2 = 0) then
begin
writeln();
exit;
end;
write('.');
Nf := 0;
for i := n2 downto 1 do
begin
Nf := (HexToInt(s[i]) + Nf) / base_in;
end;
k2 := 0;
while ((Nf <> 0) AND (k2 < 5)) do
begin
inc(k2);
write(IntToHex(floor(Nf*base_out)));
Nf := ((Nf*base_out));
end;
end;
begin
writeln('Введите число для перевода:');
readln(s);
if (CheckDotCount(s) = false) then
begin
writeln('Во введеном числа более 1 точки, что-то не так');
exit;
end;
writeln('Введите основание входной системы счисления:');
readln(base_in);
if (checkSS(base_in, s) = false) then
begin
writeln('Некорректная система счисления или число для этой системы счисления');
exit;
end;
writeln('Введите основание выходной системы счисления:');
readln(base_out);
if (checkSSR(base_out) = false) then
begin
writeln('Некорректная система счисления или число для этой системы счисления');
exit;
end;
s1 := getStringBeforeDot(s);
s2 := getStringAfterDot(s);
IntConverter(s1,base_in,base_out);
DotConverter(s2,base_in,base_out);
readln;
end.
На PascalABC нет некоторых функций, зато есть другие.
Версия для PascalABC
program test;
var
s, s1,s2 : string; // число для перевода
base_in : integer; // Основание входной системы счисления
base_out : integer; // Основание выходной системы счисления
function CheckDotCount(s: string): boolean; // Проверка количества точек в числе
var
count, i : integer;
begin
count := 0;
for i := 1 to Length(s) do
if (s[i] = '.') then inc(count);
if (count > 1) then CheckDotCount := false
else CheckDotCount := true;
end;
function IntToHex(ds: byte): string;
const
b: string = '0123456789ABCDEF';
begin
if (b[(ds shr 4) + 1] = '0') then
Result:= b[(ds and $F) + 1]
else Result:= b[(ds shr 4) + 1] + b[(ds and $F) + 1];
end;
function HexToInt(s: string): Longword;
var
b: Byte;
c: Char;
begin
Result := 0;
s := UpperCase(s);
for b := 1 to Length(s) do
begin
Result := Result * 16;
c := s[b];
case c of
'0'..'9': Inc(Result, Ord(c) - Ord('0'));
'A'..'F': Inc(Result, Ord(c) - Ord('A') + 10);
end;
end;
end;
function checkSS(base : integer; s : string): boolean;
var
i: integer;
flag : boolean;
begin
flag := true;
for i := 1 to Length(s) do
begin
if (HexToInt(s[i]) >= base) then flag := false;
end;
if ((base > 16) or (base < 2)) then flag := false;
Result := flag;
end;
function checkSSR (base : integer):boolean;
begin
if ((base > 16) or (base < 2)) then Result := false
else
Result := true;
end;
function getStringBeforeDot(s:string): string;
//pos : integer;
begin
if (Pos('.',s) = 0) then Result := s
else Result := Copy(s, 1,Pos('.',s)-1);
end;
function getStringAfterDot(s: string):string;
begin
if (Pos('.',s) = 0) then Result := ''
else
Result := copy(s,Pos('.',s)+1,Length(s));
end;
procedure IntConverter(s:string; base_in : integer; base_out : integer);
var
n1,N,i,r1 : integer;
d1 : array [0..255] of integer;
begin
n1 := Length(s);
N := 0;
for i := 1 to n1 do
begin
N:= N*base_in+HexToInt(s[i]);
end;
if (N = 0) then write ('0')
else
begin
r1 := 0;
while (N <> 0) do
begin
d1[r1] := N mod base_out;
N := N div base_out;
inc(r1);
end;
for i:=r1-1 downto 0 do
write(IntToHex(d1[i]));
end;
end;
procedure DotConverter(s:string; base_in : integer; base_out : integer);
var
n2 , i, k2: longint;
Nf : double;
begin
n2 := Length(s);
if (n2 = 0) then
begin
writeln();
exit;
end;
write('.');
Nf := 0;
for i := n2 downto 1 do
begin
Nf := (HexToInt(s[i]) + Nf) / base_in;
end;
k2 := 0;
while ((Nf <> 0) AND (k2 < 20)) do
begin
inc(k2);
write(IntToHex(Floor(Nf*base_out)));
Nf := ((Nf*base_out));
end;
end;
begin
writeln('Введите число для перевода:');
readln(s);
if (CheckDotCount(s) = false) then
begin
writeln('Во введеном числе более 1 точки, что-то не так');
exit;
end;
writeln('Введите основание входной системы счисления:');
readln(base_in);
if (checkSS(base_in, s) = false) then
begin
writeln('Некорректная система счисления или число для этой системы счисления');
exit;
end;
writeln('Введите основание выходной системы счисления:');
readln(base_out);
if (checkSSR(base_out) = false) then
begin
writeln('Некорректная система счисления или число для этой системы счисления');
exit;
end;
s1 := getStringBeforeDot(s);
s2 := getStringAfterDot(s);
IntConverter(s1,base_in,base_out);
DotConverter(s2,base_in,base_out);
readln;
end.
Исполняемые файлы:
Внимание, PascalABC и, соответственно, его версия исполняемых файлов требует .Net Framework Версии 4. Он встроен в Windows 8, но его нужно включить в компонентах Windows.
Скрины:

