La risposta accettata va bene, ma questo è C++; possiamo fare di meglio Iniziamo con la nostra classe Bignum
, con un numero di cifre totalmente illimitato.
Per la massima efficienza, lavoreremmo con numeri binari puri, impacchettando ogni elemento dell'array con tutti i bit che possiamo gestire in modo efficiente. L'approccio più semplice consiste nel memorizzare una singola cifra decimale in ciascun elemento. Qui sono andato per un compromesso, memorizzando 9 cifre decimali in ogni elemento uint32_t
.
I dati vengono memorizzati little-endian, poiché è molto più semplice estendere uno vector
alla fine quando sono necessari elementi di ordine superiore.
Una volta che abbiamo questa classe, la funzione fattoriale è la semplicità stessa.
#include <assert.h>
#include <iomanip>
#include <iostream>
#include <stdint.h>
#include <vector>
class Bignum
{
public:
Bignum(int value)
{
assert(value >= 0 && value <= 999999999);
parts.push_back(value);
}
Bignum& operator*=(int rhs)
{
assert(rhs >= 0 && rhs <= 999999999);
uint32_t carry = 0;
for (size_t i = 0; i < parts.size(); i++)
{
uint64_t product = (uint64_t)parts[i] * (uint64_t)rhs + carry;
parts[i] = (uint32_t)(product % 1000000000LL);
carry = (uint32_t)(product/1000000000LL);
}
if (carry != 0)
parts.push_back(carry);
return *this;
}
friend std::ostream & operator<<(std::ostream& stream, const Bignum& num);
private:
std::vector<uint32_t> parts;
};
inline std::ostream& operator<<(std::ostream& stream, const Bignum& num)
{
char oldfill = stream.fill('0');
for (std::vector<uint32_t>::const_reverse_iterator it = num.parts.rbegin(); it != num.parts.rend(); it++)
stream << *it << std::setw(9);
stream.fill(oldfill);
stream.width(0);
return stream;
}
Bignum factorial(int n)
{
Bignum fac = 1;
for (int i = 2; i <= n; i++)
fac *= i;
return fac;
}
int main(int argc, char* argv[])
{
for (int n = 0; n <= 52; n++)
std::cout << factorial(n) << std::endl;
return 0;
}
fonte
2014-02-25 04:45:20
Quale linguaggio di programmazione? –
C++ in base al tag. – Drakosha