Calcolo del fattoriale con iterazione

di il
22 risposte

Calcolo del fattoriale con iterazione

Buon pomeriggio,

mi chiedevo se potevate darmi una mano con questo programma. In sè funziona, ma se provo a lanciare il programma e a mettere numeri elevati ad esempio 85 o 120 mi restituisce fattoriale uguale a 0… Come mai?? sareste così gentili da aiutarmi??

Poi ho provato a rifarlo senza funzioni, e inserendo i numeri grandi come 122 mi calcola il fattoriale con l'esponente, mi chiedevo se c'era un modo per vedere il numero in maniera estesa…

Grazie mille in anticipo

#include <iostream>
using namespace std;
 
long fattoriale(int f)
{
    long fatt = 1;
 
    for (int k = f; k > 0; k--) {
        fatt = fatt *=k;
    }
 
    return fatt;
}
 
int main()
{
    int f;
    cout<<"Inserisci il numero per saperne il fattoriale: ";
    cin>>f;
    cout<<"Il fattoriale di "<<f<<" è "<< fattoriale(f);
 
    return 0;
}

22 Risposte

  • Re: Calcolo del fattoriale con iterazione

    85 ! = 
    2817104114380550276949479442260611594800566343305742064051019127525600\
    26159795933451040286452340924018275123200000000000000000000

    120 ! = 
    6689502913449127057588118054090372586752746333138029810295671352301633\
    5572449629893668741652719849813081576378932140905525344085894081218598\
    98481114389650005964960521256960000000000000000000000000000

    122 ! =
    9875044200833601362411579871448208012564404136978359605958470050267671\
    4572050143649033796427745042294071023050579626404736512939596842694895\
    821378210620013388054747214795243520000000000000000000000000000


    Nota: “ x ! ”  e' il modo in cui in matematica si indica “fattoriale(x)”.
    Giusto per essere sicuro che la sintassi sia chiara ;-)

    Secondo te quale e' il problema ?

    ;-)

  • Re: Calcolo del fattoriale con iterazione

    Sai che tipo di dati esistono nel linguaggio C e i loro limiti?

    Con il long (a 32 bit) puoi gestire fino a 2147483647 (poco più di 2 miliardi).

    Già 13! equivale a 6.227.020.800 e quindi non puoi usare un long oltre il 12! (e neanche con un unsigned long).

    Con un long long (a 64 bit) arrivi a 18.446.744.073.709.551.616 … fatti i conti … e capirai che il fattoriale prevede risultati elevati che non puoi gestire facilmente con i tipi interi del C

  • Re: Calcolo del fattoriale con iterazione

    Come ben saprai, il tipo long è a 32 bit (come il tipo int; per usare 64 bit bisogna definire variabili di tipo long long int), quindi il numero più grande di cui puoi calcolare il fattoriale è 12. Già con il 13 superi il numero massimo che puoi rappresentare con i long int (che è 2 ^ 31 meno 1 ) o gli unsigned long int (che è 2 ^ 32 meno 1 ).

    Anticipato da oregon e migliorabile mentre scrivevo :)

  • Re: Calcolo del fattoriale con iterazione

    Ciao, si tratta di un problema di overflow, nel senso che il tipo long (che presumo corrisponda ad un intero con segno a 32 bit) non è abbastanza capiente per numeri così grandi come quelli che stai cercando di calcolare. 

    Giusto per rendere l'idea: il massimo valore esprimibile da un intero a 32 bit è 2.147.483.647, mentre 15! = 1.307.674.368.000.

    Nel seguente codice utilizzo interi senza segno a 64 bit, i quali consentono di calcolare al massimo 20!:

    #include <iostream>
    #include <cstdint>
    
    using namespace std;
    
    uint64_t fattoriale(uint8_t n)
    {
        uint64_t f = 1;
        for(; n > 1; f *= n--);
        return f;
    }
    
    int main()
    {
        int n;
        cout << "--> ";
        cin >> n;
        cout << "f(" << n << ") = " << fattoriale(n);
    }
  • Re: Calcolo del fattoriale con iterazione

    30/01/2023 - oregon ha scritto:


    Sai che tipo di dati esistono nel linguaggio C e i loro limiti?

    Con il long (a 32 bit) puoi gestire fino a 2147483647 (poco più di 2 miliardi).

    Già 13! equivale a 6.227.020.800 e quindi non puoi usare un long oltre il 12! (e neanche con un unsigned long).

    Con un long long (a 64 bit) arrivi a 18.446.744.073.709.551.616 … fatti i conti … e capirai che il fattoriale prevede risultati elevati che non puoi gestire facilmente con i tipi interi del C

    Se io volessi fare il fattoriale di 120?? Come posso fare??

    Perche con quest'altro che ho fatto funziona?? Mi chiedevo se si potesse fare anche con la funzione!?!?

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        
        int numero;
        long double fattoriale;
        cout<<"Inserire un numero intero positivo per saperne il fattoriale: ";
        cin>>numero;
        fattoriale=1;
        for(int i = 1; i <= numero; i++)
        fattoriale = fattoriale*i;
        cout<<"Il fattoriale di "<<numero<<" è: "<<fattoriale;
    
        return 0;
    }
  • Re: Calcolo del fattoriale con iterazione

    I long double sono minimo a 80 bit (dipende dal sistema e dal compilatore) e usano una diversa rappresentazione. Comunque non ti da tutte le cifre perché usa la notazione esponenziale per numeri grandi.
    Per vedere tutte le cifre di un numero molto grande bisogna fare programmi appositi in cui vai a manipolare le singole cifre (o blocchi di cifre) che compongono il numero.

  • Re: Calcolo del fattoriale con iterazione

    30/01/2023 - euscar ha scritto:


    I long double sono minimo a 80 bit (dipende dal sistema e dal compilatore), quindi prova a fare il calcolo del numero più grande che puoi rappresentare. Comunque non ti da tutte le cifre perché usa la notazione esponenziale per numeri grandi.

    Si anche se con notazione esponenziale una parvenza di fattoriale lo fa, con la funzione è possibile farlo anche se con notazione esponenziale??

  • Re: Calcolo del fattoriale con iterazione

    Se vuoi tutte le cifre l'unica cosa è ricorrere ad una libreria per i big-int.

  • Re: Calcolo del fattoriale con iterazione

    30/01/2023 - puffetta blu ha scritto:


    Si anche se con notazione esponenziale una parvenza di fattoriale lo fa, con la funzione è possibile farlo anche se con notazione esponenziale??

    Perché no? Basta sostituire il tipo intero con quello in virgola mobile.

  • Re: Calcolo del fattoriale con iterazione

    30/01/2023 - Nippolo ha scritto:


    30/01/2023 - puffetta blu ha scritto:


    Si anche se con notazione esponenziale una parvenza di fattoriale lo fa, con la funzione è possibile farlo anche se con notazione esponenziale??

    Perché no? Basta sostituire il tipo intero con quello in virgola mobile.

    Potresti aiutarmi con la libreria per i big-int e dirmi cortesemnte dove mettere il double

    #include <iostream>
    
    using namespace std;
    long double fattoriale(int f){
        
        long fatt = 1;
     
        for (int k = 1; k <= f; k++) {
            fatt = fatt *=k;
        }
     
        return fatt;
    }
     
    int main()
    {
        long double a;
        cout<<"Inserisci il numero per saperne il fattoriale: ";
        cin>>a;
        cout<<"Il fattoriale di "<<a<<" è: "<< fattoriale(a);
     
        return 0;
    }
  • Re: Calcolo del fattoriale con iterazione

    Ho trovato questo esempio, ma richiede una certa conoscenza delle classi:

    https://www.geeksforgeeks.org/bigint-big-integers-in-c-with-example/

    Personalmente non ho mai lavorato con interi superiori ai long long int, quindi devi studiarti un po' il codice, altrimenti aspetta qualcuno che possa fornirti maggiore aiuto.

  • Re: Calcolo del fattoriale con iterazione

    30/01/2023 - puffetta blu ha scritto:


    Potresti aiutarmi con la libreria per i big-int e dirmi cortesemnte dove mettere il double

    Con riferimento al codice che ho postato in precedenza, basta semplicemente sostituire gli uint64_t con dei double.

    Per quanto riguarda i big-int si possono trovare varie librerie in rete, ma volendo puoi anche implementarla da sola, il modo più semplice è quello di rappresentare i numeri come stringhe ed implementare gli algoritmi relativi alle classiche operazioni su carta insegnate alle elementari (nel tuo caso sarebbe sufficiente la moltiplicazione, e quindi l'addizione).

    In ogni caso, se posso chiederlo, qual è lo scopo di calcolare questi fattoriali? Se si tratta di una questione didattica ok, ma se ti serve solo il risultato puoi sempre ricorrere a WolframAlpha.

  • Re: Calcolo del fattoriale con iterazione

    30/01/2023 - Nippolo ha scritto:


    30/01/2023 - puffetta blu ha scritto:


    Potresti aiutarmi con la libreria per i big-int e dirmi cortesemnte dove mettere il double

    Con riferimento al codice che ho postato in precedenza, basta semplicemente sostituire gli uint64_t con dei double.

    Per quanto riguarda i big-int si possono trovare varie librerie in rete, ma volendo puoi anche implementarla da sola, il modo più semplice è quello di rappresentare i numeri come stringhe ed implementare gli algoritmi relativi alle classiche operazioni su carta insegnate alle elementari (nel tuo caso sarebbe sufficiente la moltiplicazione, e quindi l'addizione).

    In ogni caso, se posso chiederlo, qual è lo scopo di calcolare questi fattoriali? Se si tratta di una questione didattica ok, ma se ti serve solo il risultato puoi sempre ricorrere a WolframAlpha.

    Si è una cosa didattica!!! 

  • Re: Calcolo del fattoriale con iterazione

    Solitamente si usa la libreria gmp, sennò va benissimo il link che ti ha messo euscar.

    Ma onestamente, usare classi o librerie esterne mi sembra presto per le tue conoscenze. 

    Accontentati di arrivare a 20! o di usare le stringhe come ti ha indicato nippolo

Devi accedere o registrarti per scrivere nel forum
22 risposte