Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [pascal] Нахождение факториала 100 
V
    Опции темы
FraiDex
Дата 16.12.2009, 23:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 4.3.2008

Репутация: нет
Всего: нет



user posted image


Это сообщение отредактировал(а) FraiDex - 16.12.2009, 23:52
PM MAIL WWW ICQ   Вверх
mr.Anderson
Дата 17.12.2009, 00:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 16
Всего: 128



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


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
FraiDex
Дата 17.12.2009, 01:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 4.3.2008

Репутация: нет
Всего: нет



Спасибо буду разбираться. Ещё вопрос, как предварительно узнать число элементов в массиве? Оно ведь изначально неизвестно.
PM MAIL WWW ICQ   Вверх
t_gran
Дата 17.12.2009, 10:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 621
Регистрация: 13.11.2007
Где: г.Усть-Илимск

Репутация: 33
Всего: 37



Цитата

Оно ведь изначально неизвестно

А вы ограничьте тип, ведь стандартные типы данных тоже свои лимит имеют. В общем предлагаю свой код, правда написан с колена т.к. времени достаточно не было. В результате проверку на лимит расчёта не делал, но под ваши требования она в принципе подходит (я имею в виду расчёт факториала).
Код

const
   CLength= 256;
type
   TDigit= array [0..CLength] of word; // В '0'-ом указывается фактическая длина числа
{-----------------------------------------------}
// Конвертируем longint в TDigit
procedure PushDigit (var theDig: TDigit; theOrigDig: longint);
var
   i: word;
begin
   i:= 0;
   while (theOrigDig <> 0) do
   begin
      inc(i);
      theDig[i]:= theOrigDig mod 10;
      theOrigDig:= theOrigDig div 10;
   end;
   theDig[0]:= i;
end;
{-----------------------------------------------}
// Выполняем смещение влево на заданное количесво позиций
function DisplaceLeft (theDig: TDigit; theStep: word): TDigit;
var
   i: word;
   result: TDigit;
begin
   for i:= 1 to theStep do
      result[i]:= 0;
   for i:= 1 to theDig[0] do
      result[i+theStep]:= theDig[i];
   result[0]:= theDig[0] + theStep;
   DisplaceLeft:= result;
end;
{-----------------------------------------------}
function SummDigit (theOneDig, theTwoDig: TDigit): TDigit;
var
   i, buff: word;
   result: TDigit;
   pOneDig, pTwoDig: ^TDigit; // Первый - меньшее число, второй - большее
begin
   if (theOneDig[0] < theTwoDig[0]) then
   begin
      pOneDig:= @theOneDig;
      pTwoDig:= @theTwoDig;
   end
   else
   begin
      pOneDig:= @theTwoDig;
      pTwoDig:= @theOneDig;
   end;
   buff:= 0;
   for i:= 1 to pTwoDig^[0] do
   begin
      if (pOneDig^[0] < i) then
         pOneDig^[i]:= 0;
      result[i]:= pOneDig^[i] + pTwoDig^[i] + buff;
      if (result[i] < 10) then
         buff:= 0
      else
      begin
         buff:= 1;
         result[i]:= result[i] mod 10;
      end;
   end;
   if (buff <> 0) then
   begin
      inc(i);
      result[i]:= buff;
   end;
   result[0]:= i;
   SummDigit:= result;
end;
{-----------------------------------------------}
// Умножаем второе число на первое
function MultipliDigit (theOneDig, theTwoDig: TDigit): TDigit;
var
   i, j, buff: word;
   result, temp: TDigit;
begin
   PushDigit(result, 0);
   for j:= 1 to theTwoDig[0] do
   begin
      buff:= 0;
      for i:= 1 to theOneDig[0] do
      begin
         temp[i]:= theOneDig[i] * theTwoDig[j] + buff;
         if (temp[i] < 10) then
            buff:= 0
         else
         begin
            buff:= temp[i] div 10;
            temp[i]:= temp[i] mod 10;
         end;
      end;
      if (buff <> 0) then
      begin
         inc(i);
         temp[i]:= buff;
      end;
      temp[0]:= i;
      result:= SummDigit(result, DisplaceLeft(temp, j-1));
   end;
   MultipliDigit:= result;
end;
{-----------------------------------------------}
procedure PrintDigit (theDig: TDigit);
var
   i: word;
begin
   for i:= theDig[0] downto 1 do
      write(theDig[i]);
end;
{-----------------------------------------------}
function Factorial (theNumber: longint): TDigit;
var
   i: longint;
   result, temp: TDigit;
begin
   PushDigit(result, 1);
   for i:= 1 to theNumber do
   begin
      PushDigit(temp, i);
      result:= MultipliDigit(result, temp);
   end;
   Factorial:= result;
end;
{-----------------------------------------------}

var
   i: longint;
begin
   write('Число для вычисления факториала: ');
   readln(i);
   write('Результат: ');
   PrintDigit(Factorial(i));
end.


Если нужен более высокий порядок, то поменяйте значение константы CLength на необходимое. Только учитывайте, что размерность ограничена типом WORD. Если нужно ещё больше, то укажите другой тип. Понимаю, что такой подход ресурсо-неэкономичный, но я уже писал, что писалось всё с колена. ООП бы сюда прикрутить, было бы удобнее. smile

Это сообщение отредактировал(а) t_gran - 17.12.2009, 10:07


--------------------
Я знаю, что ничего не знаю© Сократ
user posted image
PM MAIL WWW   Вверх
FraiDex
Дата 10.1.2010, 00:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 4.3.2008

Репутация: нет
Всего: нет



а может есть у кого решение самой задачи?
PM MAIL WWW ICQ   Вверх
mr.Anderson
Дата 10.1.2010, 04:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 16
Всего: 128



Цитата
Спасибо буду разбираться

Цитата
а может есть у кого решение самой задачи?

Неужели надоело разбираться? smile 


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
hkdkest
  Дата 10.1.2010, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 300
Регистрация: 30.11.2008

Репутация: нет
Всего: 1



есть на дельфи исходник Факториал [Исходник на Delphi] можно переделать

user posted image
PM MAIL WWW   Вверх
FraiDex
Дата 15.1.2010, 18:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 4.3.2008

Репутация: нет
Всего: нет



Всем спасибо!!! Слава богу разобрался...
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0952 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.