![]() |
1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!
![]() |
sqrt |
![]()
Сообщение
#1
|
Группа: Пользователи Сообщений: 7 Пол: Мужской Репутация: ![]() ![]() ![]() |
Требуется найти факториалы всех чисел от 1 до 100. Стандартный цикл не канает, т.к. в longint не влезет факториал ста... Есть подозрение что это можно реализовать рекурсией, но как? Что делать???
|
![]() ![]() |
volvo |
![]()
Сообщение
#2
|
Гость ![]() |
sqrt
Рекурсия вызывает переполнение при n = 14 То, что может помочь - длинночисленная арифметика. Смотри здесь |
sqrt |
![]()
Сообщение
#3
|
Группа: Пользователи Сообщений: 7 Пол: Мужской Репутация: ![]() ![]() ![]() |
Пасибо, попробую умножение длинных чисел.
|
Digitalator |
![]()
Сообщение
#4
|
Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 247 Пол: Мужской Репутация: ![]() ![]() ![]() |
Цитата Есть подозрение что это можно реализовать рекурсией А каким образом рекурсия вообще может спасти от переполнения? помойму она только приводит к переполнению ![]() -------------------- |
sqrt |
![]()
Сообщение
#5
|
Группа: Пользователи Сообщений: 7 Пол: Мужской Репутация: ![]() ![]() ![]() |
Что-то у меня ничего не получается... может кто поможет написать? Я делал цикл на умножение длинного числа на короткое [1;100] и сразу же печать в текстовый файл каждого факториала.. Но, видимо туплю - не получается ничего.
|
sqrt |
![]()
Сообщение
#6
|
Группа: Пользователи Сообщений: 7 Пол: Мужской Репутация: ![]() ![]() ![]() |
Люди! Что я неправильно делаю? Подскажите, плиз...
Код program factorial; const _md=1000; _osn=10000; type t_long=array[0.._md] of integer; p_long=^t_long; var a,c:p_long; i,k:integer; begin a^[0]:=1; a^[1]:=1; for k:=1 to 15 do begin write(k, ' => '); for i:=1 to a^[0] do begin c^[i+1]:=(longint(a^[i])*k+c^[i]) div _osn; c^[i]:=(longint(a^[i])*k+c^[i]) mod _osn; end; if c^[a^[0]+1]>0 then c^[0]:=a^[0]+1 else c^[0]:=a^[0]; for i:=0 to c^[0]+1 do begin a^[i]:=c^[i]; write(a^[i]); end; writeln(''); end; readln(i); end. пытаюсь найти факториалы от 1цы до 15 - нифига неправильно ![]() Сообщение отредактировано: sqrt - 21.12.2004 12:50 |
volvo |
![]()
Сообщение
#7
|
Гость ![]() |
sqrt
Держи правильную программу (она пишет факториалы чисел 1 - 100 в файл "fact_100.txt"): Код Const Base = 10000; { system base } maxLen = 300; { max digits length } { digits delimiter for output, '|' for example } DigitSep: String = ''; { getting max of (Base-1) and (MaxLen), so } { we could store length in the array item } Max = (Base-1+MaxLen+Abs(Base-1-MaxLen)) Div 2; Type Digit = 0..Pred(Base); { type for the digit storing } Inter = 0..Pred(Base)*Succ(Base); { type for the temporary use } Index = 0..maxLen; { type for the digis number storing } { type for the very long integer (VLI) storing } { item #0 stores number of digits in VLI } LargeInt = Array [0..MaxLen] Of 0..Max; { called when overflow detected } Procedure Overflow(Const s : String); Begin WriteLn('Error:'#1310'Overflow when making ', s); Halt(1) End; { LargeInt initialization by (x) number -- A := x } { ASSERT: using LongInt instead of Digit, } { guessing that MaxLongInt >= Base-1 } Procedure Init(Var A: LargeInt; x: LongInt); Var i: Index; Begin FillChar(A, SizeOf(A), 0); i := 0; Repeat If i = maxLen Then Overflow('Init'); Inc(i); A[i] := x mod Base; x := x div Base Until x = 0; A[0] := i End; { A := A * x } Procedure MulDigit(Var A: LargeInt; x: Digit); Var i: Index; T: Inter; Begin T := 0; For i := 1 To A[0] Do Begin T := Inter(A[i])*x + T; A[i] := T mod Base; T := T div Base End; If T > 0 Then Begin If A[0] = maxLen Then Overflow('MulDigit'); Inc(A[0]); A[A[0]] := T End End; { A := n! } Procedure Fact(Var A: LargeInt; n: LongInt); Var T: LargeInt; i: LongInt; Begin Init(T, 1); For i := 2 To n Do MulDigit(T, i); A := T End; { Printing LargeInt -- Write(A) } Procedure Print(Var f: Text; Const A: LargeInt); Var i: Index; k: Digit; s: String; Begin Str(Base - 1, s); k := Length(s); Write(f, A[A[0]]); For i := A[0]-1 DownTo 1 Do Begin Str(A[i], s); While Length(s) < k Do s := '0' + s; Write(f, DigitSep, S) End End; { main program } Var f: LargeInt; i: LongInt; out: Text; begin Assign(out, 'fact_100.txt'); ReWrite(out); For i := 1 To 100 do Begin Fact(f, i); Print(out, f); writeln(out); writeln(out) End; Close(out) end. |
sqrt |
![]()
Сообщение
#8
|
Группа: Пользователи Сообщений: 7 Пол: Мужской Репутация: ![]() ![]() ![]() |
volvo
Спасибо большое! |
xds |
![]()
Сообщение
#9
|
![]() N337 ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 737 Пол: Мужской Репутация: ![]() ![]() ![]() |
shr offtop,1
В детстве баловался: Код program FuckToReal; const DataSize = 16384; ResultSize = 60000; type PResult = ^TResult; TResult = array[0..0] of Char; var Data: array[0..DataSize - 1] of Word; Result: PResult; Digits, N: Integer; SymbolIndex, i: Word; begin GetMem(Result, ResultSize); Write('N>'); Readln(N); FillChar(Data, SizeOf(Data), 0); Data[0] := 1; Digits := 1; Write('Calculating... '); { Calulating of factorial by long binary multiplication } asm push bp mov bp,N @@NextPass: push ds pop es lea si,Data mov di,si cld xor bx,bx mov cx,Digits @@NextDigit: lodsw mul bp add ax,bx adc dx,0 stosw mov bx,dx loop @@NextDigit or bx,bx jz @@Exit inc Digits mov cx,1 jmp @@NextDigit @@Exit: dec bp cmp bp,1 ja @@NextPass pop bp end; Writeln('Done'); Write('Converting... '); { Building a decimal representation of long binary number } SymbolIndex := ResultSize; asm push bp mov bp,Digits dec bp shl bp,1 lea bp,Data[bp] les di,Result add di,ResultSize-1 mov bx,10 std @@NextSymbol: xor dx,dx mov si,bp cmp [si],bx jae @@NextDigit sub bp,2 @@NextDigit: lodsw div bx mov [si+2],ax cmp si,offset Data jae @@NextDigit mov al,dl add al,'0' stosb dec SymbolIndex cmp bp,offset Data jae @@NextSymbol pop bp end; Writeln('Done'); for i := SymbolIndex to ResultSize - 1 do Write(Result^[i]); Writeln; FreeMem(Result, ResultSize); end. Считала 10000! (с точностью до едениц) на Pentium 100 MHz за 37 секунд. -------------------- The idiots are winning.
|
![]() ![]() |
![]() |
Текстовая версия | 18.07.2025 17:14 |