Calcolo del fattoriale con iterazione

di puffetta blu il
22 risposte

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

  • 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 ?

    ;-)

  • 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

  • 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 :)

  • 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);
    }
  • 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;
    }
  • 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.

  • 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??

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

  • 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.

  • 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;
    }
  • 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.

  • 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.

  • 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!!! 

  • 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