2016-02-19 2 views
3

Мне нужно ввести это уравнение, и в нем есть факториал. Я хотел бы знать, если есть что-то вроде * = умножение или мощн (1,3) для факториала чего-то в С.Как вы пишете факториал в C?

term = pow(-1, K) * pow(x, 2K)/(2K) 

Факториал будет последний 2K.

+2

Там отсутствует встроенный в стандартной функции, вам нужно написать свою собственную факториальную реализацию. –

+0

Не могли бы вы дать мне указание на то, как я смогу это сделать? – DanielRossi

+0

Один из способов: используйте 'for'loop от' 1' до '2K' и разделите термин' term' на каждый номер. –

ответ

2

Не существует предопределенной функции для факториала, но она может быть рекурсивно реализована следующим образом.

int factorial(int a) 
{ 
    if (0 == a) 
     return 1; 
    else 
     return a * factorial(a - 1); 
} 

Пользователи, которым нравится ?, могут выполнять функцию следующим образом.

int factorial(int a) 
{ 
    return 0 == a ? 1 : (a * factorial(a - 1)); 
} 

Если требуется нерекурсивная формулировка, реализация может быть выполнена следующим образом.

int factorial(int a) 
{ 
    int Result = 1; 
    for (int i = a; i > 0; Result *= i, i--); 
    return Result; 
} 
3

Если по какой-то причине рекурсивные функции оставит вас чесать голову, вы также можете реализовать его без рекурсии:

/* calculate n factorial */ 
unsigned long long nfact (int n) 
{ 
    if (n <= 1) return 1; 

    unsigned long long s = n; 

    while (--n) 
     s *= n; 

    return s; 
} 

(примечание: это до вас, чтобы вы осуществить тест для переполнения, если необходимо)

+0

Я думаю, что это может быть дополнительно улучшено, если вы положите 'if (n <= 1) return 1;' вместо 'if (n <= 0) return 1;' в конце концов, 1! = 1. Конечно, 'while' также необходимо скорректировать:' while (n--> 1) ' – Ian

+0

Вы знаете, что вы были на 100% прав. Сделано изменение. Спасибо!. Теперь это в хорошей форме ':)' Посмотрите внимательно на 'n -', это не совсем 'n -' это '--n', что объясняет сокращение. –

+0

А, да. Ты прав. Я не заметил 's = n;' ':)' правильное направление, как вы говорите ... – Ian

0
long fact(int num) 
{ 
if(num==0) 
    return 1; 
else 
    return num*fact(num-1); 
} 

Включите вышеуказанный код и позвоните этому методу, чтобы получить факториал числа.

5

Редко вам нужна функция для вычисления факториалов. Факториалы растут так быстро, что таблица поиска достаточно для нескольких значений, для которых вычисление не переполняется. Если вы вычисляете термины в цикле, вы можете избежать вычисления факториала с использованием аккумулятора на весь срок.

K = 0; 
term = 1; 

while (K<N) { 

    /* use term */ 
    do_something_with(term); 

    /* update term for new value of K */ 
    K += 1; 
    term = -term * x*x/(2*K*(2*K-1)); 
} 

Если это кажется неясным для вас, вы можете сначала получить эту программу, где аккумуляторы являются явными, а затем объединить шаг обновления в одной переменной, как и выше. Эта программа по-прежнему будет иметь проблемы с раздуванием факториалов.

K = 0; 
pow_minus_1_K = 1; 
pow_x_2K = 1; 
factorial_2K = 1; 

while (K<N) { 

    /* compute term */ 
    term = pow_minus_1_K * pow_x_2K/factorial_2K; 

    /* update accumulators for new value of K */ 
    K += 1; 
    pow_minus_1_K = -pow_minus_1_K; 
    pow_x_2K *= x*x; 
    factorial_2K *= 2*K*(2*K-1); 
} 
5

Факториалы легко вычислить, ведь n! является просто произведением всех чисел до п. Но есть практическая проблема: Factorials overflow pretty quickly. 32-битный int может содержать 12 !, 64-битный int 20 !.

В зависимости от того, как ваша серия сходится, вы можете переполнить допустимый диапазон.

С приближением серии, как ваша, как правило, лучше, чтобы найти средства для представления термин K с помощью термина к − 1. В вашем случае:

term = pow(-1, k) * pow(x, 2*k)/fact(2*k) 

вы можете представлять термин как

term[k + 1] = -term[k] * pow(x, 2)/((2*k - 1) * (2*k - 2)) 

и ваша серия становится:

double f(double x) 
    { 
     double term = 1.0; 
     double res = term; 
     int k = 0; 

     while (k < 100) { 
      double old = res; 

      term = -term * (x/(2*k + 1)) * (x/(2*k + 2)); 
      res += term; 

      if (res == old) break; 
      k++; 
     } 

     return res; 
    } 

Эта функция будет использовать в большинстве 100 итераций для вычисления косинуса. Он останавливается, когда этот термин не способствует результату.На практике он достигает результата с примерно 10 итерациями, поэтому в этом случае регулярные факториальные вычисления были бы достаточно точными. Тем не менее, вычисление их снова и снова является расточительным.

2

Я думаю, что использование рекурсии для этой проблемы - хороший способ начать работу с рекурсией и понять, как она работает, но она недостаточно эффективна, так как вы каждый раз вызываете функцию. Если вы хотите знать, почему, сделайте тест и посмотрите, сколько времени потребуется. Хотя я должен сказать, что итеративный метод не намного лучше.

От кодекса Полная Стив Макконнелл:

Не использовать рекурсию для факториалов или чисел Фибоначчи

Одна из проблем с компьютерной науки учебников является то, что они представляют глупые примеры рекурсии. Типичными примерами являются вычисление факториала или вычисление последовательности Фибоначчи. Рекурсия - мощный инструмент, и это действительно глупо использовать в любом из этих случаев. Если программист , который работал для меня, использовал рекурсию для вычисления факториала, я бы нанял кого-то еще .

Так что помните об этом, когда переходите к рекурсивным версиям, которые публикуются здесь. Теперь, как написать.

В основном у вас есть базовый футляр, если число меньше 1 и общий рекурсивный случай. Обычно вы используете базовый регистр и рекурсивный случай в рекурсивной функции. Для факториала, это будет выглядеть примерно так:

int factorial_rec(int number) 
{ 
    if (number == 0) 
    { 
     return 1; 
    }else 
    { 
     return number * factorial_rec(number - 1); 
    } 
} 
0

Код, чтобы найти факториал заданного числа с использованием рекурсивного алгоритма может быть, как показано ниже:

#include<stdio.h> 
int fact(int n) 
{ 
    if(!n) 
     return 1; 
    else 
     return (n*fact(n-1)); 
} 
void main() 
{ 
    int n; 
    printf("Enter number : "); 
    scanf("%d",&n); 
    printf("\nFactorial of %d is : %d",n,fact(n)); 
} 
Смежные вопросы