Câu trả lời được chấp nhận là tốt, nhưng đây là C++; chúng ta có thể làm tốt hơn. Hãy bắt đầu lớp Bignum
của riêng chúng tôi, với số chữ số hoàn toàn không bị chặn.
Để đạt hiệu quả cao nhất, chúng tôi sẽ làm việc với các số nhị phân thuần túy, đóng gói từng phần tử mảng với nhiều bit khi chúng ta có thể xử lý hiệu quả. Cách tiếp cận đơn giản hơn là lưu trữ một chữ số thập phân duy nhất trong mỗi phần tử. Ở đây tôi đã đi cho một sự thỏa hiệp, lưu trữ 9 chữ số thập phân trong mỗi yếu tố uint32_t
.
Dữ liệu được lưu trữ ít người dùng, vì việc mở rộng vector
ở cuối cùng dễ dàng hơn nhiều khi chúng tôi cần các yếu tố đặt hàng cao hơn.
Khi chúng tôi có lớp này, hàm giai thừa là tính đơn giản.
#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;
}
Nguồn
2014-02-25 04:45:20
Những ngôn ngữ lập trình? –
C++ theo thẻ. – Drakosha