>Думать отучают.
А то что Scheme умеет манипулировать бесконечными числами думать не отучает? Таже gmp библиотека умеет складывать, умножать и т.д. большии числа. Если бы я вместо mpz_fac_ui использовал mpz_mul_ui было бы лучше? И я бы стал "думающим" программистам?
Попробовал я написать с нуля функцию реализующую вычисление факториала. К сожалению она работает очень медленно (26 секунд для 100000!, хотя 10000! она считает почти мгновенно). Такие вещи, конечно, написать сразу эффективно непросто. Набросок кода:
#include <stdio.h>
#include <stdlib.h>
#define MAX_BIG_VALUE 1000000000
struct BigInt {
unsigned long long* value;
unsigned long length;
};
void big_init(struct BigInt* big_int, unsigned long long value) {
big_int->value = calloc(1, sizeof (unsigned long long));
big_int->value[0] = value;
big_int->length= 1;
}
void big_print(struct BigInt* big_int) {
long i;
int flag = 0;
unsigned long len = big_int->length;
for (i = len - 1; i >= 0; i--) {
if ((flag == 0) && (big_int->value[i] != 0)) {
flag = 1;
printf("%llu", big_int->value[i]);
} else if (flag == 1) {
printf("%09llu", big_int->value[i]);
}
}
}
void big_multiplication(struct BigInt* big_int, unsigned long long value) {
unsigned long i;
unsigned long j;
unsigned long len = big_int->length;
for (i = 0; i < len; i++) {
big_int->value[i] *= value;
}
for (i = 0; i < len; i++) {
if (big_int->value[i] >= MAX_BIG_VALUE) {
unsigned long long tmp = big_int->value[i] / MAX_BIG_VALUE;
if ((i + 1) >= len) {
unsigned long start = big_int->length;
unsigned long finish = 20 + big_int->length;
big_int->length += 20;
//big_int->length++;
big_int->value = realloc(big_int->value, sizeof(unsigned long long) * big_int->length);
for (j = start; j < finish; j++)
big_int->value[j] = 0;
}
big_int->value[i + 1] += tmp;
big_int->value[i] -= MAX_BIG_VALUE * tmp;
}
}
}
int main(int argc, char **argv) {
struct BigInt big;
big_init(&big, 1);
unsigned long long i;
for (i = 2; i <= 100000; i++) {
big_multiplication(&big, i);
//if ((i % 10000) == 0) printf("%llu\n", i);
}
big_print(&big);
return EXIT_SUCCESS;
}