Newsgroup: it.comp.lang.pascal
Titolo: Il fattoriale

Ciao a tutti.
    Sto facendo un programma per il calcolo delle probablilità:
combinazioni, disposizini, permutazioni, etc..
Purtoppo però, nell'eseguire il calcolo del fattoriale, ottengo facilmente
un overflow... Se inserisco un numero maggiore di 33 il programma mi da'
errore..
Esiste il modo per non provocare l'overflow??
Ah, sto usando TP per windows... se può servire!
Ho visto che la calcolatrice di win esegue i fattoriali anche molto alti: se
lo può fare la calcolatrice di windows, perchè non un mio programma?
;-)
Grazie
AX1S

Esiste il modo per non provocare l'overflow??
Be' ! non sara' molto ortodosso, ma funziona :
{$n+}
function fatt(n : extended) : extended;
begin
  if n = 1 then fatt := 1
  else fatt := n * fatt(n-1);
end;
Il massimo fattoriale calcolabile e' quello di 630 (se non ricordo male
all'incirca 8*10^1435), ma il limite e' dettato dalle dimensioni dello stack.
Andrea, mica uno qualunque...
--------------------------------------------------
"Ho cambiato signature, si vede ?"
--
Posted from 
itaca.ulysse.it
 [195.223.254.1]
via Mailgate.ORG Server - 
http://www.mailgate.org

Un bel di' Ippopapero Acquatico scrisse:
IA> Be' ! non sara' molto ortodosso, ma funziona :
IA> 
IA> {$n+}
IA> 
IA> function fatt(n : extended) : extended;
IA> begin
IA>   if n = 1 then fatt := 1
IA>   else fatt := n * fatt(n-1);
IA> end;
IA> 
IA> Il massimo fattoriale calcolabile e' quello di 630 (se non ricordo male
IA> all'incirca 8*10^1435), ma il limite e' dettato dalle dimensioni dello stack.
IA> 
Mmm... ricorsiva... :-)
Perche' non un semplice:
function fatt(n: extended): extended;
begin
 fatt := 1;
 for i := 1 to n do
    fatt := fatt * n;
end;
Comunque sia, anche nella ver. ricorsiva, 0! = 1, quindi bisogna correggere:
	if n = 0 then fatt := 1
Ciao!
-- 
"Quando c'e' bisogno di toccar ferro o legno, ci si accorge che il mondo e'
fatto di alluminio e vinile", legge di Flugg
-- 
Emanuele Cesena
em...@iol.it
          occhio all'antispam NOSPAM!
http://www.geocities.com/SiliconValley/Grid/8879





Ricorsione a tutti i costi eh?  :-))
E in un baleno ti sei mangiato tutto lo stack e non arrivi neanche
all'overflow.
Utilizzando il 'normale' metodo della FOR arrivi fino in fondo
superando il fattoriale di 1700.
1754!=1,979*10^4930
Riporto la procedura per completezza, ma e' sicuramente nota a tutti.
{$n+}
function   fatt(n:integer):extended;
var	i:integer;
	f:extended;
begin
	f:=1;
	for i:=2 to n do
	     f:=f*i;
	fatt:=f
end;
Ciao,  Fabio
fabi...@rocketmail.com

	if n = 0 then fatt := 1
Si, e' giusto, l'intento era evitare di eseguire una moltiplicazione in piu' per
1.


1754!=1,979*10^4930
Si, e' vero, la versione iterativa e' piu' efficiente di quella ricorsiva.
In realta' avevo trasposto per il tipo 'extended' la stessa versione della
funzione ricorsiva che usavo per il tipo 'int', senza rendermi conto del consumo
di memoria troppo eccessivo.


end;
velocizzando un po' le cose :
function fatt(n : word) : extended;
var f : extended;
begin
    f := 1;
    while (n > 1) do
    begin
      f := f * n;
      n := n - 1;
    end;
    fatt := f;
end;
Andrea, mica uno qualunque...
----------------------------------------------------------------
"Sopra il camper la capra campa, sotto il camper la capra crepa"


end;
E cosa avresti velocizzato????
Credi veramente che una WHILE+CONTATORE sia piu' veloce di una FOR?
Fabio
fabi...@rocketmail.com

Credi veramente che una WHILE+CONTATORE sia piu' veloce di una FOR?
No, ma si accede a una variabile di meno ('i' non c'e' piu'). ;))
Skyscraper


Un bel di' Andrea Laforgia scrisse:
AL> Si', hai ragione, la ricorsione in questo caso e' troppo dispendiosa.
AL> 
ok!
AL> Si, e' giusto, l'intento era evitare di eseguire una moltiplicazione in piu' per
AL> 1.
AL> 
ok!
P.S: ma quanti nomi c'hai!=!?=?!?|? :-)
-- 
"Se non capite una parola in un brano scientifico, ignoratela. Il brano ne
potra' benissimo fare a meno", legge di Cooper


Un bel di' Skyscraper scrisse:
S> No, ma si accede a una variabile di meno ('i' non c'e' piu'). ;))
S> 
S> 
Miii... 4 bytes in piu'!!!!! :-)))))
(4 bytes, parlo degli int del C... in Pascal sono addirittura 2 bytes!!) :-)
-- 
"Se c'e' una maniera di rimandare una decisione importante, la buona
burocrazia, pubblica o privata, la trovera'", quinta legge di Parkinson


(4 bytes, parlo degli int del C... in Pascal sono addirittura 2 bytes!!) :-)
Scusate l'OT, ma se vogliamo essere precisi ( e poi devi specificare il
compilatore :) ) le dimensioni degli interi del C (con il DJGPP) sono :
sizeof ( char )  =  1        
sizeof ( short ) =  2        
sizeof ( int )   =  4        
sizeof ( long )  =  4
con il Borland C++ invece rispettivamente 1, 2, 2, 4.
:)
Si' ma comunque e' una caxxata, tanto la routine di Fabio gira piu' velocemente
....
Skyscraper (apprezzatelo adesso : eviterete la coda)
----------------------------------------------------
 
andrea_...@bigfoot.com
----------------------------------------------------


Un bel di' Skyscraper scrisse:
S> Scusate l'OT, ma se vogliamo essere precisi ( e poi devi specificare il
S> compilatore :) ) le dimensioni degli interi del C (con il DJGPP) sono :
S> 
non vorrei dire eresie, ma non dipende dal compilatore, bensi' dallo
standard... (e lo standard e' a 32bit).
Che poi il compilatore della borland metta gli int a 16bit... sono
affari suoi :-)
(anche perche' il C++ della borland, se non sbaglio, e' quello per
DOS...)
bye!
-- 
"1. Un funzionario vorra' sempre moltiplicare i suoi subordinati, non i rivali
 2. I funzionari creano lavoro l'uno per l'altro", assiomi di Parkinson


con il Borland C++ invece rispettivamente 1, 2, 2, 4.
Attento, cio' e' vero se il Borland C++ e' impostato con un target a
32 bit. Se imposti il target a 16 bit, i valori sono rispettivamente
1,2,2,4.
Bye.
Jo Parrello - OWL/C++ Programmer
http://www.geocities.com/SiliconValley/Hills/8145
(
jopar...@geocities.com
)

DOS...)
Non significa nulla il sistema operativo, c'entra l'architettura della macchina.


>DOS...)
S> 
S> Non significa nulla il sistema operativo, c'entra l'architettura della macchina.
S> 
certo: quello che volevo dire e' che e' per qualcosa di vecchio... :-)
Ma poi non c'entra, in qualche modo, il sistema operativo?? Voglio dire, se io
posso, in DOS, usare solo registri a 16 bit, fare calcoli con interi a 32bit e'
piu' lento che non a 16, per questo scelgo di mettere gli int a 16bit.
Quando invece posso accedere ai registri a 32bit (o piu'), che senso ha utilizzare
interi a 16bit!? :-)
-- 
"1. Se hai dubbi, bofonchia
 2. Se hai problemi, delega", leggi di Boren


interi a 16bit!? :-)
Tutto si valuta in base alle esigenze dei programmi.
Allocare un array di 1000 "shortint" e' dicuramente meno dispendioso che
allocarne uno di 1000 "longint".


Un bel di' Skyscraper scrisse:
S> No, il s.o. non c'entra nulla.
S> 
ah, ok! :-)
Grassie per le infos ;-)
'ao!
-- 
"1. Se si tiene qualcosa abbastanza a lungo lo si potra' buttare
 2. Qualsiasi cosa si butti, servira' non appena non sara' piu'
disponibile", leggi complementari di Richard sulla proprieta'
