Помощь - Поиск - Пользователи - Календарь
Полная версия: Вычисление факториала
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Евгений
Здравствуйте!
Дана задача по вычислению факториала, с которой вроде справился, но есть ограничения: "тип обработанных данных-longint, если результат не помещается в 4 байта программа должна сообщить об этом"
Вот что написал:
Program Factoreal;
uses crt;
var
N: longint;
M,I: integer;
Begin
clrscr;
N:=1;
write('введите число>=0 ');
readln(M);
if M=0 then N:=1
else
for I:=1 to M do
N:=N*I;
writeln ('Факториал равен:',' ',N);
readln;
end.


Как добиться того чтобы программа сообщала о переполнении? Перепобовал многое, но в итоге только еще больше запутался.
Может есть у кого какие идеи?
Lapp
Цитата(Евгений @ 27.11.2010 20:11) *
Может есть у кого какие идеи?
Тут не нужно никаких идей.
12! = 479001600
а
13! = 6227020800
Максимальное число, влезающее в longint есть 2147483647 (если я правильно помню))
То есть 12! влезает в 4 байта, а 13! уже нет. Если на вход получаешь число >12, то пишешь, что переполнение.
Евгений
Ну это ,то что первое приходит в голову, ограничить ввод чисел после 12. Я думал, что есть еще какие то решения.
volvo
Решения есть, но они либо для 32-битных компиляторов, либо для ассемблерных вставок. Я так понимаю, ни одно ни другое тебя не устроит?
Lapp
Цитата(Евгений @ 29.11.2010 23:11) *
Ну это ,то что первое приходит в голову, ограничить ввод чисел после 12. Я думал, что есть еще какие то решения.
Жень, ты бы направил мысль в нужное русло И сэкономил отвечающим время, если бы сразу написал, какое решение тебя устраивает, а какое - нет. А так - написанное (подробно) мной решение абсолютно соответствует условию.

Внимание, вопрос! Где твое "спасибо"? norespect.gif
Евгений
Дико извиняюсь за не вежливость! Конечно же спасибо!
А по поводу какое решения устраивает, сам не знаю, заочник я, нахожусь от универа в 700 верстах и какое решение устроит преподователя неизвесно)).
Krjuger
Ну раз заочник,то когда получаеш задание,досканально выпытывай у преподавателя,чо именно ему надо,в каком виде представить.В общем пытай,пока сам досканально не поймеш,что от тебя требуется,либо пока тебе не дадут полную волю действия.Если не можеш во время получения задания,то возьми какое нибудь мыло у него или любую связь для контакта,чтобы всегда можно было утонить задание.
Lapp
Извинения приняты.

Во время получения всего не учтешь, это невозможно. Но мне кажется, что всегда можно спросить по мылу. Тут же я имел в виду, что просто скзать о своих мыслях. Ты же даже привел прогу. Такая простая вещь как проверка if M>12 могла бы там быть, если тебе это приходило в голову. Ладно, проехали smile.gif.

Напиши, в чем ты работаешь. Какой компилятор используешь?
Евгений
Borland Turbo Pascal 7.0
Lapp
Цитата(Евгений @ 30.11.2010 6:01) *
Borland Turbo Pascal 7.0

Ммм... Ну, можно сделать вот так:

{$R-}
var
N,K: longint;
M,I: integer;
Overflow: boolean;

Begin
write('введите неотрицательное число: ');
readln(M);
N:= 1;
i:= 1;
Overflow:= false;
while not Overflow and (i<=M) do begin
K:=N*I;
Overflow:= (N<>k div i);
N:=K;
Inc(i)
end;
if Overflow then WriteLn('Overflow')
else writeln (M,'! = ',N);
readln;
end.

Этот способ будет работать, но мне он не нравится. Изврат это.

Добавлено через 1 мин.
И имей в виду (на всяк случай) - в FPC это не пойдет.
volvo
Кстати, способ, который работает в любом компиляторе:
var
res: real;
N: longint;
M, I: integer;
Begin
N:=1;
write('M [ >= 0 ] = '); readln(M);
if M = 0 then N := 1
else
for I := 1 to M do
begin
res := 1.0 * N * I;
if res > maxlongint then
begin
writeln('error: overflow'); halt;
end
else n := trunc(res);
end;
writeln ('M! = ', N);
readln;
end.
Lapp
Цитата(volvo @ 30.11.2010 9:28) *
Кстати, способ, который работает в любом компиляторе:
var
res: real;
N: longint;
M, I: integer;
Begin
N:=1;
write('M [ >= 0 ] = '); readln(M);
if M = 0 then N := 1
else
for I := 1 to M do
begin
res := 1.0 * N * I;
if res > maxlongint then
begin
writeln('error: overflow'); halt;
end
else n := trunc(res);
end;
writeln ('M! = ', N);
readln;
end.

Тут есть небольшая неопределенность (которая вряд ли где приведет к ошибке, впрочем), следующая из неопределенности длины мантиссы. Для пущей уверенности лучше использовать double или extended..
Но если уж использовать maxlongint (и, собсно, почему бы нет? оно, наверное, есть везде..)), то тогда лучше уж сделать так, мне кажется (без действительных типов):
var
N: longint;
M,I: integer;
Overflow: boolean;

Begin
N:=1;
write('введите неотрицательное число: ');
readln(M);
N:=1;
i:=1;
while not Overflow and (i<=M) do begin
Overflow:= N > maxlongint div i;
if not Overflow then N:=N*I;
Inc(i)
end;
if Overflow then WriteLn('Overflow')
else writeln (M,'! = ',N);
readln;
end.
Евгений
Спасибо вам большое! Думаю сделать три варианта решения, а преподаватель пусть решает, какой его устроит)).
Связаться с ним не могу, т.к., я его даже не видел, задание получал на кафедре у секретаря.
Есть еще один интересный для меня вопрос, но попробую его поискать, если не найду , тогда подниму в другой теме..
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.