Silnia - komputer 64 bitowy jest w stanie obliczyć max. 20! - trochę mnie to nie satysfakcjonuje - zrobimy, że będzie liczył więcej...
Zacznijmy od standardowego algorytmu wyliczającego silnię
Kod w języku ANSI C operującym na 64 bitowych zmiennych - wiem, nuda - do konkretów przejdę za chwilę ;-)
#include <stdio.h>
int main(void) {
unsigned long res = 1;
int num;
printf("\nEnter factorial value: ");
scanf("%d", &num);
for(int i = 2; i <= num; i++) {
res *= i;
}
printf("\nFactorial of %d = %ld\n\n", num, res);
return 0;
}
Powyższa, standardowa metoda jest w stanie wyliczyć 20! (limit CPU - 64 bity)Brzmi to mało satysfakcjonująco, więc w dalszej części zajmiemy się tym limitem ;-)
Wrzucam zrzut ekranu z podanym max. parametrem dla powyższej metody (większy zrobiłby przepełnienie):

Tak sobie pomyślałem, że dodam pętle i wyświetle wszystkie liczby w zakresie 64 bitowym:

Jeszcze taki mały żarcik z algorytmu na silnię, na zrzucie ekranu
wersja w pliku wsadowym bash (w DOS/Windows takie pliki to *.bat -> batch)

To by było na tyle z 64 bitami, czas przejść do ciekawszej części...
Tu jest mała pokazówka przekroczenia 64 bitów, granice liczenia ustawiłem na 99!
Nie - nie jest to górna granica możliwości, po prostu chciałem, aby każda liczba
mieściła się w jednej linijce ;-)
Jakby ktoś pomysłowy chciał się przyczepić do zer na końcu liczb,
są one wynikiem mnożeń przez liczby mające przeważnie na końcu 0 lub 5 (np. 10 dodaje liczbie jedno 0),
więc wszystko gra, możecie mi zaufać lub sprawdzić na piechotę ;-)

Poniżej zamieszczam kod na silnię ograniczony do obliczenia 25000!,
ale po drobnej modyfikacji da się nim obliczyć, nawet 100000!.
Nie wiem, jaka jest jego górna granica, jakoś nie chciało mi się tego sprawdzać,
moim zdaniem, taki wynik jest dość satysfakcjonujący.
(Screenshot pokazujący od 1! do 99! to ten sam sposób, tylko trochę zmodyfikowany,
aby pokazywał cały zakres wyników)
#include <stdio.h> #define digits 99094 int main(void) { int num1, factorial = 1, multiplicator = 1, tens = 0, zeros = 0, counter = 0; long fin[digits]; printf("\n\033[1;31m---------- FACTORIAL WITH 64 BITS LIMIT EXCEEDED (Limit set to 25000!) ----------\n"); printf("\nEnter number to calculate factorial: "); scanf("%d", &num1); printf("\n"); if(num1 > 25000) { printf("Limit exceeded! Exit... (Limit is set to 25000!)"); } else { for(int i = 0; i < digits; i++) { fin[i] = 0; } fin[digits - 1] = 1; for(int j = 0; j < num1; j++) { for(int i = digits - 1; i >= 0; i--) { fin[i] = fin[i] * multiplicator; } multiplicator++; factorial = j + 1; for(int l = digits - 1; l >= 0; l--) { fin[l] = fin[l] + tens; if(fin[l] > 9) { tens = fin[l] / 10; fin[l] -= tens * 10; } else tens = 0; } } printf("\033[1;34m%d! = \033[1;32m", factorial); for(int j = 0; j < digits; j++) { if(fin[j] == 0) zeros++; if(fin[j] != 0) break; } for(int k = zeros; k < digits; k++) { counter++; } for(int k = zeros; k < digits; k++) { printf("%d", fin[k]); } printf("\n\n\033[1;37m----- Digits Count: %d -----", counter); } printf("\n\n"); return 0; }