50!
- это очень большое число, для представления которого требуется почти 150 бит. Тип данных long long
предоставляет только 64 бита.Итак, C не может делать вычисления так, как вы это делаете;он переполняется.
Для этой цели вы можете использовать библиотеку арифметических пакетов произвольной точности.Этот вид библиотеки представляет числа с переменным числом битов и предлагает операции, которые не переполняются.
gmp - библиотека Gnu MP Bignum , является примером такой библиотеки.Есть и другие.Вот как вы можете сделать это с помощью gmp.(не отлажено).
#include "gmp.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int main(int argc, char * argv[]){
uint n;
uint m;
mpz_t nn;
mpz_t mmn;
mpz_t mmm;
mpz_t denom;
mpz_t result;
char * str;
if (argc <= 2){
printf ("Usage: %s <number> <number> \n", argv[0]);
return 1;
}
n = atoi(argv[1]);
m = atoi(argv[2]);
mpz_fac_ui (nn,n); /* nn = n! */
mpz_fac_ui (mmn,n-m); /* mmn = (n-m)! */
mpz_fac_ui (mmm,m); /* mmm = m! */
mpz_mul(denom, mmm, mmn); /* denom = mmn * mmm */
mpz_fdiv_q(result, nn, denom); /* result = nn / denom */
str = mpz_get_str (null, 10, const mpz_t result);
printf ("deal %d from %d: %s combinations\n", n,m, str);
free (str);
mpz_clear(nn);
mpz_clear(mmm);
mpz_clear(mmn);
mpz_clear(denom);
mpz_clear(result);
return 0;
}
Другая возможность: использовать тот факт, что (n!) / (n-m)!
равно произведению целых чисел от (m + 1 до n).Например, 50!/ 47!
- это 48 * 49 * 50
.Это должно во многих случаях сохранять ваши целые числа представимыми в 64 битах.И даже лучше, когда вы выполняете такую компьютерную арифметику, вам не нужно выполнять фактическую операцию деления, потому что она выпадает прямо из формул.