Помощь - Поиск - Пользователи - Календарь
Полная версия: Две задачи на системы счисления
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
-Chester-
Друг попросил помочь, а я, мягко говоря, в программировании не силен unsure.gif
Если не трудно, помогите пожалуйста... Не дайте, так сказать ударить в грязь лицом...

ЗАДАЧА 1: Перевести число, представленное в системе счисления с основанием S, в системы счисления с основаниями P, Q, R. Обеспечить корректность ввода числа в системе счисления с основанием S. Перевод чисел реализовать с применением функций. (Разработайте функцию для перевода числа из системы счисления с основанием S в систему счисления с основанием P, а затем, функции для перевода из P в Q и из P в R.) Не использовать стандартных возможностей по вводу/выводу чисел представленных в 2-ой, 8-ой, 16-ой системах счисления. Для представления цифр больших 9 использовать заглавные буквы латинского алфавита.
ЗАДАЧА 2: Вывести на экран в виде таблицы значения чисел из интервала от A до B с шагом C в системах счисления с основаниями S, P, Q, R. Числа A, B, C задаются в системе счисления с основанием S, A>=0, B>A. Обеспечить точность 5 знаков после запятой во всех системах счисления. Разработайте функцию для сложения двух чисел в системе счисления с основанием S.
S=7 P=10 Q=19 R=28
volvo
Цитата(Правила Раздела)
3. Прежде чем задавать вопрос, см. "FAQ",если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!

Это - перевод из одной системы в другую:
FAQ: Общие вопросы по математике

Ну, а это выдал поиск:
3 несложные задачи
Этого вполне достаточно для решения задачи...
-Chester-
Volvo Честное слово очень неловко отвлекать вас всякими мелочами, но скажу честно, я вообще никогда не писал на Паскале, поэтому FAQ для меня малопонятен, если можно обьясните подоступней как можно решить эти задачи, что и как надо сделать (мне надо ведь не только написать эти программы, но еще потом и человеку обьснить, что к чему). Буду вам крайне признателен...
volvo
Цитата
я вообще никогда не писал на Паскале

-Chester-, в таком случае Вы явно ошиблись адресом, потому что если я и напишу программу (или это сделает кто-то другой, не важно), понять ее Вы не сможете (если уж "разжеванных" программ из FAQ не понимаете, а второй раз так разжевывать никто не будет, сделают набросок и все), а уж объяснить тем более...
Guest
Ну тогда хоть набросок сделайте...
klem4
Наброски Volvo дале тебе в виде ссылок во втором посте, там есть приктически все что тебе нужно ...
Guest
Если не затруднит, проверьте решение ЗАДАЧИ№1:

program test;
uses crt;
var n : string;

function ToDec(n:string; radix:longint):longint;
var
m, i: longint;
const
digit: string[28]='0123456789ABCDEFGHIJKLMNOPQRS';
begin
m:=0;
while n[1]='0' do delete(n,1,1);
for i:=1 to length(n) do
m:=m*radix+pos(n[i],digit)-1;
ToDec:=m;
end;

function FromDec(n, radix:longint):string;
var
s: String;
const
digit: string[28]='0123456789ABCDEFGHIJKLMNOPQRS';
begin
s:='';
repeat
s:=digit[(n mod radix)+1]+s;
n:=n div radix;
until n=0;
FromDec:=s;
end;

function FromDec2(n, radix:longint):string;
var
s: String;
const
digit: string[28]='0123456789ABCDEFGHIJKLMNOPQRS';
begin
s:='';
repeat
s:=digit[(n mod radix)+1]+s;
n:=n div radix;
until n=0;
FromDec2:=s;
end;

begin
clrscr;
readln(n);
writeln(todec(n,7));
writeln(fromdec((todec(n,7)),19));
writeln(fromdec((todec(n,7)),28));
readln;
end.
:cwm33:
klem4
Вот мне всегда нравились такие посты : проверьте пожалуйста, а самому ? Берешь исходные данные, делаешь ручной рассчет в тетрадке, потом запускаешь программу с этими исходными данными и сравниваешь ответы, если сошлисьь, значит работает привильно.
dry.gif
volvo
Guest, во-первых, если уж копируешь программу, то указывай, откуда.

А во вторых - объясни мне, зачем нужны 2 одинаковых функции FromDec и FromDec2?
Guest
Вроде бы все работает, но вот никак не получается сделать чтобы числа в системах от 11 ричной и выше заменялись соответствующими буквами

program test;
uses crt;
var n : integer;

function FromDec(n, radix:longint):string;
var
s: String;
const
digit: string[16]='0123456789ABCDEF';
begin
s:='';
repeat
s:=digit[(n mod radix)+1]+s;
n:=n div radix;
until n=0;
FromDec:=s;
end;

function ToDec(n:string; radix:longint):longint;
var
m, i: longint;
const
digit: string[16]='0123456789ABCDEF';
begin
m:=0;
while n[1]='0' do delete(n,1,1);
for i:=1 to length(n) do
m:=m*radix+pos(n[i],digit)-1;
ToDec:=m;
end;

begin
clrscr;
readln(n);
writeln(fromdec(n,7));
writeln(todec(fromdec(n,7),19));
writeln(todec(fromdec(n,7),28));
readln;
end.

ВЗЯТО ИЗ FAQ
volvo
Guest, Внимательнее будь!
Для того, чтобы перевести число "11111" в (7)-ой системе счисления в систему с основанием (19), нужно:
writeln( fromdec(todec('11111', 7), 19) );
, а не то, что у тебя было... Чувствуешь разницу? Число НЕ в 10-ной с/с, следовательно должно вводиться в строку, преобразовываться в (10), а оттуда в (19). А ты делал наоборот: вводил число в 10-ной с/с, преобразовывал (10) в (7), и потом вообще непонятно что преобразовывал в (19)...
Guest

program test;
uses crt;
var n : string;

{ ... }

begin
clrscr;
readln(n);
writeln(todec(n,7));
writeln(fromdec(todec(n,7),19));
writeln(fromdec(todec(n,7),28));
readln;
end.


Исправил вроде, но nea.gif что-то мне кажется здесь не то, и так еще раз попорядку:
1. N-строковая переменная, но ведь по идее вводимое число семиричное?"Обеспечить корректность ввода числа в системе счисления с основанием S", может я что-то упустил???
2. ToDec(перевод ИЗ семиричной В десятичную)
3. FromDec(перевод ИЗ десятичной В девятнадцатиричную)
4. FromDec(перевод ИЗ девятнадцатиричной В двадцативосьмиричную)
На всякий случай скажу, что работу программы я проверял по универсальному переводчику систем счисления, PASCOD которого нашел на одной из аналогичных тем данного форума...
volvo
Стоп...
Цитата
4. FromDec(перевод ИЗ девятнадцатиричной В двадцативосьмиричную)

Не то nea.gif FromDec НЕ МОЖЕТ переводить НИ ИЗ КАКОЙ системы, кроме как из (10), на то он и FromDecimal...
Так что вот так:

readln(n);
{
Если тебе нужен контроль введенного числа,
я во втором (!!!) посте давал ссылку. Это как раз должно быть здесь...

Повторять не буду, сколько можно...
}
writeln(todec(n,7)); { Это зачем? }

{ Перевод "n" (7) -> (10) и сразу же (10) -> (19)... В итоге: (7) -> (19) }
writeln(fromdec(todec(n,7),19));
{ Перевод "n" (7) -> (10) и сразу же (10) -> (28)... В итоге: (7) -> (28) }
writeln(fromdec(todec(n,7),28));

И давай прекращать копировать программы полностью !!! Приводи только тот кусок, который ТЫ написал/изменил... То что есть в FAQ мы знаем...
Guest
Вот так реализовал проверку корректности ввода (взял из универсального переводчика)

function test(n:string; osnov:integer):boolean;
var f,i:integer; mn:set of char;
begin
test:=true;
mn:=[];
for i:=0 to osnov-1 do
if i<=9 then mn:=mn+[chr(i+48)]
else mn:=mn+[chr(i+55)];
f:=ord(n[0]);
for i:=1 to f do
if (n[i]<>',') and (not(n[i] in mn)) then
begin
writeln('ERROR!It is not 7th system. Re-enter value, please');
test:=false;
i:=f;
end;
end;


Но вот осталась одна проблема при переводе в 19 и 28 системы не могу получить корректный результат. Следуя условию задачи, где сказано, что "цифры больше девяти заменять заглавными латинскими буквами" я написал вот так:

function FromDec(n, radix:longint):string;
var
s: String;
const
digit: string[28]='0123456789ABCDEFGHIJKLMNOPQR';
begin
s:='';
repeat
s:=digit[(n mod radix)+1]+s;
n:=n div radix;
until n=0;
FromDec:=s;
end;


в ToDec сделал вот так:

digit: string[7]='0123456';


В итоге получаемые результаты в 19 и 28 системах в моей программе отличаются от результатов получаемых в универсальном переводчике(в первую очередь такое происходит с большими числами). Как я понял надо использовать латиницу только до буквы F, но как при этом организовать корректное отображение результата я понять не могу.
volvo
Guest, а ты не достал уже всех своим "универсальным переводчиком"? mad.gif Или приведи его исходники (ссылку на него), или ищи ошибку у себя в программе сам !!! Откуда я знаю, ЧТО ТЫ ТАМ НАТВОРИЛ в переводчике-то !!! Судя по тому, что было тобой написано в прежних постах, и там тоже может быть все, что угодно. Лист бумаги дома есть? Вот и переведи (ВРУЧНУЮ !!!) число "1243432" из (7) -> (10) -> (19), и проверь.

А вот изменять процедуры из FAQ я бы НЕ рекомендовал... Там уже все отлажено, и все работает. Не надо умничать, если не понимаешь КАК это работает !!!
Guest
ССЫЛКА: Универсальный переводчик систем счисления
К примеру возьмем число 666666 и подставим его в мою программу получим результат:
10: 117648
19: H2H0
28: 5A1K
подставим это же число в переводчик и получим:
10: 117648
19: A2A0
28: 5A1D
Сравним результаты, в этом и состоит проблема...
Guest
Не судьба видно dry.gif
volvo
Да что ты говоришь? А РАЗОБРАТЬСЯ в работе этого пресловутого "универсального" переводчика - не судьба? Только один пример:
Цитата
function simvol(n:byte):char;
begin
  if n in [10..15] then simvol:=chr(n+55)
  else simvol:=chr(n+48);
end;

Всё !!! Однозначный диагноз: правильно работает ТОЛЬКО для систем счисления с основанием <= 16... Я добавлю эту ремарку по ссылке...

Вот, кстати, моя программа, выполняющая нужные тебе действия. И результат проверен на бумаге:
666666 (7) = 117648 (10) = H2H0 (19) ...
const
_symbols: string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';

function FromDec(n, radix:longint):string;
var
s: string;
begin
s := '';
repeat
s := _symbols[(n mod radix)+1] + s;
n := n div radix;
until n = 0;
FromDec := s;
end;

function ToDec(n:string; radix:longint):longint;
var
m, i: longint;
begin
m := 0;
while n[1] = '0' do delete(n, 1, 1);
for i := 1 to length(n) do
m := m * radix + pos(n[i],_symbols) - 1;
ToDec := m;
end;

function isCorrect(n: string; radix: longint): boolean;
var
bad: boolean;
i: integer;
begin
bad := False;
i := 0;
repeat
inc(i);
bad := (pos(n[i], copy(_symbols, 1, radix)) = 0);
until bad or (i = length(n));
isCorrect := not bad;
end;


var
s: string;

begin
write('(7) : '); readln(s);
if not isCorrect(s, 7) then writeln('error !!!')
else begin
writeln('(19): ', fromdec(todec(s, 7), 19) );
writeln('(28): ', fromdec(todec(s, 7), 28) );
end;
end.
-Chester-
Огромное спасибо за помощь в написании первой проги, отдельный респект Volvo.
Но вот вторую никак не удается одолеть:
Как я понимаю, она основывается на первой, добавляется цикл с папраметром (от A до B), но как реализовать шаг цикла (С), мне не понятно. Неясен и момент где: Обеспечить точность 5 знаков после запятой во всех системах счисления. Разработайте функцию для сложения двух чисел в системе счисления с основанием S (причем тут сложение).
Прошу прощения, что подымаю всем уже порядком поднадоевшую тему, но мне без вашей помощи кранты...
Romtek
{ Исходное число A(S) умножить на R по правилам S-арифметики. Целая часть
полученного числа представляет собой цифру b-1 числа А® . Затем, отбросив
целую часть, умножить дробную часть на R . При этом получается число, целая
часть которого есть цифра b-2 . Повторять процесс умножения l раз, пока не будут найдены все l цифр числа A®.
Взято из http://matsievsky.newmail.ru/sys-schi/rules.htm }

const
N = 0.12345678;
MaxP = 5;
epsMaxP = 1e-5; {требуемая точность}
Base = 5; {основание системы}

var
i: integer;
r, {основание в степени -i }
t, {основание в степени i (степень наращивается в цикле умножением на основание)}
Num, {исходное дробное число}
coef, {коэффициент перед r, который мы вычисляем для каждого слагаемого}
outn: single; {приближённая сумма, должна быть с точностью до MaxP знаков}

begin
Num := N;
writeln (Num:10:5);

outn := 0.0;

t := 1.0;
for i := 1 to MaxP do
begin
t := t * Base;
r := 1.0 / t; {r = base^(-i)}

Num := Num * Base; {умножаем дробную часть на основание}
coef := Trunc(Num); {Целая часть числа есть коэффициент}
Num := Num - coef; {отбрасываем целую часть}

outn := outn + coef * r;

write (coef:4:0);
end;

writeln;
writeln (outn:10:6);
end.
Эта программа вычисляет коэффициенты, но выдаваемый результат не имеет точности 1e-5, т.к. в цикле я брал только 5 цифр.
В действительности же нужно создать такой цикл, что outn будет сравниваться с N и если ошибка меньше чем epsMaxP, то прекратить его.
Вот здесь есть ещё неплохой материал: Википедия: Системы счисления
Romtek
Цитата
Как я понимаю, она основывается на первой, добавляется цикл с папраметром (от A до B), но как реализовать шаг цикла (С), мне не понятно.
Шаг в Паскале выполняется так:
x := A;
while x <= B do
begin
{...}
x := x + step;
end;
step = C (step - шаг, англ.)
-Chester-
Я все же никак не могу понять, как решить эту задачу (может надо организовать множество)...
Guest
Люююди, отзовитесь пожалуйста на крик о помощи...
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.