Newsgroup: it.comp.lang.c++
Titolo: dubbio su libro

Sto studiando il c++ sul libro "C++ fondamenti di prog." (Deitel&Deitel). In
un paragrafo dove spiega la ricorsione mi è venuto un dubbio:
perché dichiara l'argomento della funzione factorial come unsigned long se
il massimo valore che riceverà sarà quello della variabile i che arriva fino
a 10??
Posto il codice:
#include <iostream>
#include <iomanip>
using namespace std;
unsigned long factorial( unsigned long );
int main()
{
   for ( int i = 0; i <= 10; i++ )
      cout << setw( 2 ) << i << "! = " << factorial( i ) << endl;
   return 0;
}
unsigned long factorial( unsigned long number )
{
   if ( number <= 1 )
      return 1;
   else
      return number * factorial( number - 1 );
}
Ciao
Andrea

a 10??
Perche' il codice di una funzione non e' legato all'uso che se fa in
un programma particolare.
Se un altro programmatore usasse come parametro il valore 60 la
funzione dovrebbe essere in grado di calcolare il fattoriale.


L'altro programmatore dovrebbe anche avere un computer bello tosto,
perche' 60 fattoriale richiede circa 240-250 bit di rappresentazione :-)
Ciao,
Nicola

Andrea Laforgia wrote in message ...

Penso che per la funzione fattoriale si puo´ tranquillamente usare un int
come parametro visto che se passassi un numero piu´ grande di un int, il
valore di ritorno sarebbe lungo da qui alla Cina.
:-)
Maurus

valore di ritorno sarebbe lungo da qui alla Cina.
Vabbe', a parte il fatto che non sappiamo su quale piattaforma questo
programma girera', credo che il senso del discorso fosse chiaro.
Applicandolo a tutte le funzioni, si puo' dire che il codice di una
funzione, se sa di poter operare su valori che spaziano in grandi
intervalli, fa bene ad utilizzare come tipo del valore di ritorno
quello capace di contenere il massimo di tali valori, perche' DEVE
prescindere da quelli che saranno i suoi parametri nei programmi in
cui verra' utilizzata.

perche' 60 fattoriale richiede circa 240-250 bit di rappresentazione :-)
8,3209871127413901442763411832234e+81
Calcolato con la calcolatrice di Windows :))

Appunto per questo non capisco l'utilizzo di unsigned long int. Inoltre
essendo un libro per principianti dovrebbe motivare il perché per una
funzione che accetta un valore massimo di 10 dichiara un dato del genere.
Ciao
Andrea
Maurus <REMOVE...@rocketmail.com-REMOVE> wrote in message
9f5lc4$fgs$1...@newstoo.ericsson.se...



Appunto :-) Tra parentesi ho sbagliato i conti. 10^81 richiede circa 270
bit. Non conosco computer che gestiscano unsigned long cosi' grandi :-)
Ciao,
Nicola

funzione che accetta un valore massimo di 10 dichiara un dato del genere.
Ma chi l'ha detto che la funzione accetta un valore massimo di 10 ?
Se io scrivo la seguente funzione :
int func( int a )
{ 
    return a + 1 ;
}
e poi la uso con :
int main()
{
    for ( int i = 1 ; i <= 10 ; i++ )
    {
        int k = func( i ) ;
    }
}
non posso mica affermare che la funzione accetta un valore massimo di
10, solo perche' nel mio main il ciclo va da 1 a 10.
Viceversa, se scrivo :
int func( int a ) 
{
    return ( a > 10 ) ? -1 : a + 1 ;
}
allora si', posso affermare che la mia funzione accetta un valore
massimo di 10 e restituisce in caso di errore -1.

 funzione che accetta un valore massimo di 10 dichiara un dato del genere.
Sospetto che sia per garantire il massimo valore calcolabile
esattamente, senza dover introdurre problemi di promozione o conversione
implicita tra tipi diversi.
Ciao,
Nicola

 i che arriva fino a 10??
perchè un unsigned long sta tutto dentro un registro di CPU

perchč un unsigned long sta tutto dentro un registro di CPU
Non e' detto.
L'unico tipo esattamente equivalente alla parola macchina e' l'intero.


Ma io non sto parlando del valore di ritorno che e´ giustamente un unsigned
long, ma del parametro della funzione fattoriale, che nell´esempio era anche
esso:
unsigned long factorial( unsigned long );
Per cui Andrea che ha postato il quesito si chiedeva come mai la funzione
avesse come parametro un unsigned long visto che il massimo valore passatole
era 10 nell´esempio.
Giustamente tu dici che una funzione non deve guardare al caso specifico,
per cui non e´ che la funzione fattoriale debba cambiare il tipo del suo
parametro solo perche´ nel main le passiamo solo dei valori da 1 a 10.
Pero´ visto che si parla di fattoriale, basta un unsigned int come parametro
e un unsigned long come valore di ritorno.
Maurus

Nicola
Ciao Nicola,
non ho capito bene il tuo dubbio, se il codice fosse stato cosi´ non ci
sarebbero stati problemi di promozione o di conversione implicita, o
sbaglio?
#include <iostream>
#include <iomanip>
using namespace std;
unsigned long factorial( unsigned int );
int main()
{
   for ( int i = 0; i <= 10; i++ )
      cout << setw( 2 ) << i << "! = " << factorial( i ) << endl;
   return 0;
}
unsigned long factorial( unsigned int number )
{
   if ( number <= 1 )
      return 1;
   else
      return number * factorial( number - 1 );
}
Maurus

 Maurus
    ^
Bocciato :-)
Ciao,
Nicola

 e un unsigned long come valore di ritorno.
Se e' per questo puoi saturare un unsigned long come output anche con il
fattoriale di un intero di pochi bit. Quindi potresti avere come tipo del
parametro in ingresso anche un unsigned char.
L'unica ragione valida per mantenere uguali il tipo di ingresso e quello di
uscita e' sottolineare che il fattoriale e' una funzione definita fra numeri
dello stesso insieme (in senso matematico). Ovvero gli interi positivi. Che poi
tu non possa avere una seria funzione fattoriale in C++ senza fare uso di una
classe (nella fattispecie una di aritmetica intera a precisione variabile)
questo e' un altro discorso.
In un linguaggio dinamicamente tipizzato e che possiede tale classe come parte
della libreria standard (per esempio Smalltalk, ma anche altri) il problema non
sussiste.
--
Andrea Ferro
---------
Brainbench C++ Master. Scored higher than 97% of previous takers
Scores: Overall 4.46, Conceptual 5.0, Problem-Solving 5.0
More info 
http://www.brainbench.com/transcript.jsp?pid=2522556

"Andrea Laforgia" <xx...@xxxxx.xxx> wrote in message
news:e2ochtgrvq41job1c...@4ax.com...

Transcript show: 60 factorial printString
83209871127413901442763411832233643807541726063612459524492776964096000000000000
00



La funzione in oggetto (calcolo del fattoriale in C++ con valore ritornato di
tipo unsigned int) accetta come valore in ingresso (su macchine per in cui un
unsigned long e' di 32 bit) qualunque intero fra 0 e 4294967295 ma ritorna
(senza segnalare nessun errore) valori errati se l'ingresso e' superiore a 12.
E' evidentemente solo una funzione a scopo esemplificativo, non certo codice
"production quality" per il calcolo del fattoriale.


8,3209871127413901442763411832234e+81
si, ma hai perso gran parte della precisione. Non ti sembrerebbe
strano se le ultime 49 cifre terminassero realmente con 0?
Anto
--
Antonio Cuni, 19 anni, studente
Brainbench C++ Master: 4.6, higher than 98% of all previous test takers.
C Language: 3.32, higher than 79% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it

Transcript show: 60 factorial printString
Noto che c'e' una certa difficolta' nel leggere le faccine...

strano se le ultime 49 cifre terminassero realmente con 0?
E a te non sembra alquanto normale che nel mio messaggio ci siano due
(DUE) faccine ?
Ti sembra che stia considerando seriamente quel risultato ?

 strano se le ultime 49 cifre terminassero realmente con 0?
In effetti di zeri in fondo me ne aspetto quattordici.
Ciao,
Nicola


Credo che nonostante l'irregolare distribuzione di faccine pochi dei
partecipanti stiano prendendo questo thread molto sul serio ;-)
Ciao,
Nicola

strano se le ultime 49 cifre terminassero realmente con 0?
Ah, carino il Perl eh ?!? (BigInt e' standard !)
Alex
"Andrea Laforgia" <xx...@xxxxx.xxx> ha scritto nel messaggio
news:e2ochtgrvq41job1c...@4ax.com...


uno "scherzo", ho fatto una semplice prova in Perl:
Ma che stai dicendo ??? Io mi sto riferendo al MIO risultato, che
ovviamente e' calcolato in modo impreciso con la calcolatrice di
Windows... non a quello calcolato in Perl...
Ragazzi, sveglia !