Цитата | Оно ведь изначально неизвестно
|
А вы ограничьте тип, ведь стандартные типы данных тоже свои лимит имеют. В общем предлагаю свой код, правда написан с колена т.к. времени достаточно не было. В результате проверку на лимит расчёта не делал, но под ваши требования она в принципе подходит (я имею в виду расчёт факториала).
Код | 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. Если нужно ещё больше, то укажите другой тип. Понимаю, что такой подход ресурсо-неэкономичный, но я уже писал, что писалось всё с колена. ООП бы сюда прикрутить, было бы удобнее.  |