Dodaj wypisywanie bufa:
while (pom <= n)
{
cout << buf << " *= " << pom << endl;
Przetestuj ekstremalny przypadek:
1
1000 999
Podpowiem, nawet na największym typie całkowitym w tym przypadku czyli unsigned long long aka uint64_t zmienna przekręci się już przy mnożeniu przez 20. Potem będzie się swobodnie przekręcać aż dojdziemy do 0.
Czemu w końcu zawsze kończy się na zerze? Sam nie wiedziałem więc wypisałem to binarnie, dla unsigned char'a.
...
208 *= 7:
11010000 = 208
00000111 = 7
10110000 = 176
176 *= 8:
10110000 = 176
00001000 = 8
10000000 = 128
128 *= 9:
10000000 = 128
00001001 = 9
10000000 = 128
128 *= 10:
10000000 = 128
00001010 = 10
00000000 = 0
0 *= 11:
00000000 = 0
00001011 = 11
00000000 = 0
W miare rośnięcia liczby jedynki przechodzą na coraz bardziej znaczące bity aż uciekają całkowicie w pustke przepełnienia :D.
Problemy z przepełnieniami są tutaj ogromne. Zauważ, że w najbardziej ekstremalnym przypadku po skróceniu (1000 500) dalej trzeba będzie obliczyć 500*501*...*1000 / 500!. A 500! = 1.220136825 E+1134. Czyli 1135 cyfrowa liczba :D. Max dla uint64_t to liczba jakoś 20-cyfrowa. Troszke brakuje :D
Odpowiedzią byłaby biblioteka obsługująca bardzo duże liczby. Możesz też sam je obsłużyć w jakiś prymitywny sposób. Idea jest taka, żeby przechowywać liczby w tablicach mniejszych liczb i zaimplementować operacje na tych tablicach.
Być może istnieje prostsze rozwiązanie. Jak coś wymyślę to będę edytował post.
EDIT: Da się policzyć liczbę kombinacji bez liczenia silni, które powodują bardzo szybkie przepełnienia. Odpowiedź znalazłem tutaj. Jednak jeśli chcesz sam nad tym pomyśleć to nie klikaj bo to odpowiedz dana na tacy. Rozpisz sobie kilka dwumianów po skróceniu to zobaczysz bardzo prosty wzór bez wykorzystywania silni. Można go rozpisać zarówno rekurencyjnie jak i pętlą
https://stackoverflow.com/questions/41225188/issue-with-newton-binomial-coefficient-in-c