Как найти факториал?

Как я могу написать программу для поиска факториала любого натурального числа?

Это будет работать для факториала (хотя и очень малого подмножества) целых положительных чисел:

unsigned long factorial(unsigned long f) { if ( f == 0 ) return 1; return(f * factorial(f - 1)); } printf("%i", factorial(5)); 

Из-за характера вашей проблемы (и уровня, который вы допустили) это решение основано скорее на концепции решения этой задачи, а не на функции, которая будет использоваться в следующем «Механике перестановок».

Это вычисляет факториалы неотрицательных целых чисел [*] до ULONG_MAX, у которых будет так много цифр, что маловероятно, чтобы ваш компьютер мог хранить намного больше, даже если у него есть время для их расчета. Использует библиотеку с несколькими точками GNU, с которой вам нужно связать.

 #include  #include  #include  #include  void factorial(mpz_t result, unsigned long input) { mpz_set_ui(result, 1); while (input > 1) { mpz_mul_ui(result, result, input--); } } int main() { mpz_t fact; unsigned long input = 0; char *buf; mpz_init(fact); scanf("%lu", &input); factorial(fact, input); buf = malloc(mpz_sizeinbase(fact, 10) + 1); assert(buf); mpz_get_str(buf, 10, fact); printf("%s\n", buf); free(buf); mpz_clear(fact); } 

Пример вывода:

 $ make factorial CFLAGS="-L/bin/ -lcyggmp-3 -pedantic" -B && ./factorial cc -L/bin/ -lcyggmp-3 -pedantic factorial.c -o factorial 100 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 

[*] Если вы имеете в виду что-то еще по «номеру», тогда вам нужно быть более конкретным. Я не знаю никаких других чисел, для которых определяется факториал, несмотря на отважные усилия Паскаля по расширению домена с помощью функции Гамма.

Зачем делать это на C, когда вы можете сделать это в Haskell :

Программист Freshman Haskell

 fac n = if n == 0 then 1 else n * fac (n-1) 

Программист Sophomore Haskell, в Массачусетском технологическом институте (изучала схему как первокурсник)

 fac = (\(n) -> (if ((==) n 0) then 1 else ((*) n (fac ((-) n 1))))) 

Младший программист Haskell (начинающий игрок Peano)

 fac 0 = 1 fac (n+1) = (n+1) * fac n 

Другой младший программист Haskell (читайте, что n + k шаблонов являются «отвратительной частью Haskell» 1 и присоединились к «Ban n + k patterns» -movement [2])

 fac 0 = 1 fac n = n * fac (n-1) 

Старший программист Haskell (проголосовал за Никсона Бьюкенена Буша – «склоняется вправо»)

 fac n = foldr (*) 1 [1..n] 

Другой старший программист Хаскелла (проголосовал за Макговерн Биафра Надер – «наклоняется влево»)

 fac n = foldl (*) 1 [1..n] 

Еще один старший программист Haskell (наклонился так далеко, что вернулся снова!)

 -- using foldr to simulate foldl fac n = foldr (\xgn -> g (x*n)) id [1..n] 1 

Воспоминание программиста Haskell (ежедневно принимает Ginkgo Biloba)

 facs = scanl (*) 1 [1..] fac n = facs !! n 

Бессмысленный (гм) «Свободный от очков» программист Хаскелла (учился в Оксфорде)

 fac = foldr (*) 1 . enumFromTo 1 

Итеративный программист Haskell (бывший программист Pascal)

 fac n = result (for init next done) where init = (0,1) next (i,m) = (i+1, m * (i+1)) done (i,_) = i==n result (_,m) = m for ind = until dni 

Итеративный однострочный программист Haskell (бывший программист APL и C)

 fac n = snd (until ((>n) . fst) (\(i,m) -> (i+1, i*m)) (1,1)) 

Накопительный программист Haskell (создание до быстрого кульминационного момента)

 facAcc a 0 = a facAcc an = facAcc (n*a) (n-1) fac = facAcc 1 

Продолжающий прохождение Haskell программист (поднял RABBITS в первые годы, затем переехал в Нью-Джерси)

 facCps k 0 = k 1 facCps kn = facCps (k . (n *)) (n-1) fac = facCps id 

Boy Scout Haskell программист (любит привязывать узлы, всегда «почтительно», он принадлежит Церкви наименее фиксированной точки [8])

 yf = f (yf) fac = y (\fn -> if (n==0) then 1 else n * f (n-1)) 

Комбинированный программист Haskell (избегает переменных, если не обфускации, все это каррирование – это просто фаза, хотя это редко мешает)

 sfgx = fx (gx) kxy = x bfgx = f (gx) cfgx = fxg yf = f (yf) cond pfgx = if px then fx else gx fac = y (b (cond ((==) 0) (k 1)) (b (s (*)) (cb pred))) 

Список-кодирование Haskell программист (предпочитает считать в унарных)

 arb = () -- "undefined" is also a good RHS, as is "arb" :) listenc n = replicate n arb listprj f = length . f . listenc listprod xs ys = [ i (x,y) | x<-xs, y<-ys ] where i _ = arb facl [] = listenc 1 facl [email protected](_:pred) = listprod n (facl pred) fac = listprj facl 

Интерпретирующий программист Haskell (никогда «не встречал языка», который ему не нравился)

 -- a dynamically-typed term language data Term = Occ Var | Use Prim | Lit Integer | App Term Term | Abs Var Term | Rec Var Term type Var = String type Prim = String -- a domain of values, including functions data Value = Num Integer | Bool Bool | Fun (Value -> Value) instance Show Value where show (Num n) = show n show (Bool b) = show b show (Fun _) = "" prjFun (Fun f) = f prjFun _ = error "bad function value" prjNum (Num n) = n prjNum _ = error "bad numeric value" prjBool (Bool b) = b prjBool _ = error "bad boolean value" binOp inj f = Fun (\i -> (Fun (\j -> inj (f (prjNum i) (prjNum j))))) -- environments mapping variables to values type Env = [(Var, Value)] getval x env = case lookup x env of Just v -> v Nothing -> error ("no value for " ++ x) -- an environment-based evaluation function eval env (Occ x) = getval x env eval env (Use c) = getval c prims eval env (Lit k) = Num k eval env (App mn) = prjFun (eval env m) (eval env n) eval env (Abs xm) = Fun (\v -> eval ((x,v) : env) m) eval env (Rec xm) = f where f = eval ((x,f) : env) m -- a (fixed) "environment" of language primitives times = binOp Num (*) minus = binOp Num (-) equal = binOp Bool (==) cond = Fun (\b -> Fun (\x -> Fun (\y -> if (prjBool b) then x else y))) prims = [ ("*", times), ("-", minus), ("==", equal), ("if", cond) ] -- a term representing factorial and a "wrapper" for evaluation facTerm = Rec "f" (Abs "n" (App (App (App (Use "if") (App (App (Use "==") (Occ "n")) (Lit 0))) (Lit 1)) (App (App (Use "*") (Occ "n")) (App (Occ "f") (App (App (Use "-") (Occ "n")) (Lit 1)))))) fac n = prjNum (eval [] (App facTerm (Lit n))) 

Статический программист Haskell (он делает это с classом, у него есть тот фондовый Jones! После «Fun with Functional Dependencies» Томаса Холлгрена [7])

 -- static Peano constructors and numerals data Zero data Succ n type One = Succ Zero type Two = Succ One type Three = Succ Two type Four = Succ Three -- dynamic representatives for static Peanos zero = undefined :: Zero one = undefined :: One two = undefined :: Two three = undefined :: Three four = undefined :: Four -- addition, a la Prolog class Add abc | ab -> c where add :: a -> b -> c instance Add Zero bb instance Add abc => Add (Succ a) b (Succ c) -- multiplication, a la Prolog class Mul abc | ab -> c where mul :: a -> b -> c instance Mul Zero b Zero instance (Mul abc, Add bcd) => Mul (Succ a) bd -- factorial, a la Prolog class Fac ab | a -> b where fac :: a -> b instance Fac Zero One instance (Fac nk, Mul (Succ n) km) => Fac (Succ n) m -- try, for "instance" (sorry): -- -- :t fac four 

Начинающий выпускник Haskell программист (выпускное образование имеет тенденцию освобождать от мелких проблем, например, от эффективности целых чисел на аппаратных средствах)

 -- the natural numbers, a la Peano data Nat = Zero | Succ Nat -- iteration and some applications iter zs Zero = z iter zs (Succ n) = s (iter zsn) plus n = iter n Succ mult n = iter Zero (plus n) -- primitive recursion primrec zs Zero = z primrec zs (Succ n) = sn (primrec zsn) -- two versions of factorial fac = snd . iter (one, one) (\(a,b) -> (Succ a, mult ab)) fac' = primrec one (mult . Succ) -- for convenience and testing (try eg "fac five") int = iter 0 (1+) instance Show Nat where show = show . int (zero : one : two : three : four : five : _) = iterate Succ Zero Origamist Haskell programmer (always starts out with the “basic Bird fold”) -- (curried, list) fold and an application fold cn [] = n fold cn (x:xs) = cx (fold cn xs) prod = fold (*) 1 -- (curried, boolean-based, list) unfold and an application unfold pfgx = if px then [] else fx : unfold pfg (gx) downfrom = unfold (==0) id pred -- hylomorphisms, as-is or "unfolded" (ouch! sorry ...) refold cnpfg = fold cn . unfold pfg refold' cnpfgx = if px then n else c (fx) (refold' cnpfg (gx)) -- several versions of factorial, all (extensionally) equivalent fac = prod . downfrom fac' = refold (*) 1 (==0) id pred fac'' = refold' (*) 1 (==0) id pred 

Картезианский наклонный программист Haskell (предпочитает греческую еду, избегает острого индийского материала, вдохновленный «Сортировочными морфизмами» Лекса Августейна [3])

 -- (product-based, list) catamorphisms and an application cata (n,c) [] = n cata (n,c) (x:xs) = c (x, cata (n,c) xs) mult = uncurry (*) prod = cata (1, mult) -- (co-product-based, list) anamorphisms and an application ana f = either (const []) (cons . pair (id, ana f)) . f cons = uncurry (:) downfrom = ana uncount uncount 0 = Left () uncount n = Right (n, n-1) -- two variations on list hylomorphisms hylo fg = cata g . ana f hylo' f (n,c) = either (const n) (c . pair (id, hylo' f (c,n))) . f pair (f,g) (x,y) = (fx, gy) -- several versions of factorial, all (extensionally) equivalent fac = prod . downfrom fac' = hylo uncount (1, mult) fac'' = hylo' uncount (1, mult) 

Кандидат наук. Программист Haskell (съел так много бананов, что его глаза вырвались наружу, теперь ему нужны новые линзы!)

 -- explicit type recursion based on functors newtype Mu f = Mu (f (Mu f)) deriving Show in x = Mu x out (Mu x) = x -- cata- and ana-morphisms, now for *arbitrary* (regular) base functors cata phi = phi . fmap (cata phi) . out ana psi = in . fmap (ana psi) . psi -- base functor and data type for natural numbers, -- using a curried elimination operator data N b = Zero | Succ b deriving Show instance Functor N where fmap f = nelim Zero (Succ . f) nelim zs Zero = z nelim zs (Succ n) = sn type Nat = Mu N -- conversion to internal numbers, conveniences and applications int = cata (nelim 0 (1+)) instance Show Nat where show = show . int zero = in Zero suck = in . Succ -- pardon my "French" (Prelude conflict) plus n = cata (nelim n suck ) mult n = cata (nelim zero (plus n)) -- base functor and data type for lists data L ab = Nil | Cons ab deriving Show instance Functor (L a) where fmap f = lelim Nil (\ab -> Cons a (fb)) lelim nc Nil = n lelim nc (Cons ab) = cab type List a = Mu (L a) -- conversion to internal lists, conveniences and applications list = cata (lelim [] (:)) instance Show a => Show (List a) where show = show . list prod = cata (lelim (suck zero) mult) upto = ana (nelim Nil (diag (Cons . suck)) . out) diag fx = fxx fac = prod . upto Post-doc Haskell programmer (from Uustalu, Vene and Pardo's “Recursion Schemes from Comonads” [4]) -- explicit type recursion with functors and catamorphisms newtype Mu f = In (f (Mu f)) unIn (In x) = x cata phi = phi . fmap (cata phi) . unIn -- base functor and data type for natural numbers, -- using locally-defined "eliminators" data N c = Z | S c instance Functor N where fmap g Z = Z fmap g (S x) = S (gx) type Nat = Mu N zero = In Z suck n = In (S n) add m = cata phi where phi Z = m phi (S f) = suck f mult m = cata phi where phi Z = zero phi (S f) = add mf -- explicit products and their functorial action data Prod ec = Pair ce outl (Pair xy) = x outr (Pair xy) = y fork fgx = Pair (fx) (gx) instance Functor (Prod e) where fmap g = fork (g . outl) outr -- comonads, the categorical "opposite" of monads class Functor n => Comonad n where extr :: na -> a dupl :: na -> n (na) instance Comonad (Prod e) where extr = outl dupl = fork id outr -- generalized catamorphisms, zygomorphisms and paramorphisms gcata :: (Functor f, Comonad n) => (forall a. f (na) -> n (fa)) -> (f (nc) -> c) -> Mu f -> c gcata dist phi = extr . cata (fmap phi . dist . fmap dupl) zygo chi = gcata (fork (fmap outl) (chi . fmap outr)) para :: Functor f => (f (Prod (Mu f) c) -> c) -> Mu f -> c para = zygo In -- factorial, the *hard* way! fac = para phi where phi Z = suck zero phi (S (Pair fn)) = mult f (suck n) -- for convenience and testing int = cata phi where phi Z = 0 phi (S f) = 1 + f instance Show (Mu N) where show = show . int на -- explicit type recursion based on functors newtype Mu f = Mu (f (Mu f)) deriving Show in x = Mu x out (Mu x) = x -- cata- and ana-morphisms, now for *arbitrary* (regular) base functors cata phi = phi . fmap (cata phi) . out ana psi = in . fmap (ana psi) . psi -- base functor and data type for natural numbers, -- using a curried elimination operator data N b = Zero | Succ b deriving Show instance Functor N where fmap f = nelim Zero (Succ . f) nelim zs Zero = z nelim zs (Succ n) = sn type Nat = Mu N -- conversion to internal numbers, conveniences and applications int = cata (nelim 0 (1+)) instance Show Nat where show = show . int zero = in Zero suck = in . Succ -- pardon my "French" (Prelude conflict) plus n = cata (nelim n suck ) mult n = cata (nelim zero (plus n)) -- base functor and data type for lists data L ab = Nil | Cons ab deriving Show instance Functor (L a) where fmap f = lelim Nil (\ab -> Cons a (fb)) lelim nc Nil = n lelim nc (Cons ab) = cab type List a = Mu (L a) -- conversion to internal lists, conveniences and applications list = cata (lelim [] (:)) instance Show a => Show (List a) where show = show . list prod = cata (lelim (suck zero) mult) upto = ana (nelim Nil (diag (Cons . suck)) . out) diag fx = fxx fac = prod . upto Post-doc Haskell programmer (from Uustalu, Vene and Pardo's “Recursion Schemes from Comonads” [4]) -- explicit type recursion with functors and catamorphisms newtype Mu f = In (f (Mu f)) unIn (In x) = x cata phi = phi . fmap (cata phi) . unIn -- base functor and data type for natural numbers, -- using locally-defined "eliminators" data N c = Z | S c instance Functor N where fmap g Z = Z fmap g (S x) = S (gx) type Nat = Mu N zero = In Z suck n = In (S n) add m = cata phi where phi Z = m phi (S f) = suck f mult m = cata phi where phi Z = zero phi (S f) = add mf -- explicit products and their functorial action data Prod ec = Pair ce outl (Pair xy) = x outr (Pair xy) = y fork fgx = Pair (fx) (gx) instance Functor (Prod e) where fmap g = fork (g . outl) outr -- comonads, the categorical "opposite" of monads class Functor n => Comonad n where extr :: na -> a dupl :: na -> n (na) instance Comonad (Prod e) where extr = outl dupl = fork id outr -- generalized catamorphisms, zygomorphisms and paramorphisms gcata :: (Functor f, Comonad n) => (forall a. f (na) -> n (fa)) -> (f (nc) -> c) -> Mu f -> c gcata dist phi = extr . cata (fmap phi . dist . fmap dupl) zygo chi = gcata (fork (fmap outl) (chi . fmap outr)) para :: Functor f => (f (Prod (Mu f) c) -> c) -> Mu f -> c para = zygo In -- factorial, the *hard* way! fac = para phi where phi Z = suck zero phi (S (Pair fn)) = mult f (suck n) -- for convenience and testing int = cata phi where phi Z = 0 phi (S f) = 1 + f instance Show (Mu N) where show = show . int 

Уполномоченный профессор (преподавание Haskell первокурсникам)

 fac n = product [1..n] 

Благодаря Кристофу, решение C99, которое работает для нескольких «чисел»:

 #include  #include  double fact(double x) { return tgamma(x+1.); } int main() { printf("%f %f\n", fact(3.0), fact(5.0)); return 0; } 

производит 6.000000 120.000000

Для больших n вы можете столкнуться с некоторыми проблемами, и вы можете использовать приближение Стирлинга:

Который:

alt text

Если ваша основная цель – интересная функция:

 int facorial(int a) { int b = 1, c, d, e; a--; for (c = a; c > 0; c--) for (d = b; d > 0; d--) for (e = c; e > 0; e--) b++; return b; } 

(Не рекомендуется в качестве алгоритма для реального использования.)

рекурсивная версия:

 long factorial(long n) { return tr_fact(n, 1); } static long tr_fact(long n, long result) { if(n==1) return result; else return tr_fact(n-1, n*result); } 

В C99 (или Java) я буду писать факториальную функцию итеративно следующим образом:

 int factorial(int n) { int result = 1; for (int i = 2; i <= n; i++) { result *= i; } return result; } 
  • C не является функциональным языком, и вы не можете полагаться на оптимизацию хвостового вызова. Поэтому не используйте рекурсию в C (или Java), если вам не нужно.

  • Просто потому, что факториал часто используется в качестве первого примера для рекурсии, это не означает, что вам нужна recursion, чтобы вычислить его.

  • Это будет чрезмерно переполняться, если n слишком велико, как это принято в C (и Java).

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

Вот C-программа, которая использует реализацию OPENSSL BIGNUM и поэтому не особенно полезна для студентов. (Конечно, прием BIGNUM в качестве входного параметра сумасшедший, но полезный для демонстрации взаимодействия между BIGNUM).

 #include  #include  #include  #include  #include  BIGNUM *factorial(const BIGNUM *num) { BIGNUM *count = BN_new(); BIGNUM *fact = NULL; BN_CTX *ctx = NULL; BN_one(count); if( BN_cmp(num, BN_value_one()) <= 0 ) { return count; } ctx = BN_CTX_new(); fact = BN_dup(num); BN_sub(count, fact, BN_value_one()); while( BN_cmp(count, BN_value_one()) > 0 ) { BN_mul(fact, count, fact, ctx); BN_sub(count, count, BN_value_one()); } BN_CTX_free(ctx); BN_free(count); return fact; } 

Эта тестовая программа показывает, как создать число для ввода и что делать с возвращаемым значением:

 int main(int argc, char *argv[]) { const char *test_cases[] = { "0", "1", "1", "1", "4", "24", "15", "1307674368000", "30", "265252859812191058636308480000000", "56", "710998587804863451854045647463724949736497978881168458687447040000000000000", NULL, NULL }; int index = 0; BIGNUM *bn = NULL; BIGNUM *fact = NULL; char *result_str = NULL; for( index = 0; test_cases[index] != NULL; index += 2 ) { BN_dec2bn(&bn, test_cases[index]); fact = factorial(bn); result_str = BN_bn2dec(fact); printf("%3s: %s\n", test_cases[index], result_str); assert(strcmp(result_str, test_cases[index + 1]) == 0); OPENSSL_free(result_str); BN_free(fact); BN_free(bn); bn = NULL; } return 0; } 

Скомпилирован с gcc:

 gcc factorial.c -o factorial -g -lcrypto 
 int factorial(int n){ return n <= 1 ? 1 : n * factorial(n-1); } 
 #Newbie programmer def factorial(x): if x == 0: return 1 else: return x * factorial(x - 1) print factorial(6) #First year programmer, studied Pascal def factorial(x): result = 1 i = 2 while i <= x: result = result * i i = i + 1 return result print factorial(6) #First year programmer, studied C def fact(x): #{ result = i = 1; while (i <= x): #{ result *= i; i += 1; #} return result; #} print(fact(6)) #First year programmer, SICP @tailcall def fact(x, acc=1): if (x > 1): return (fact((x - 1), (acc * x))) else: return acc print(fact(6)) #First year programmer, Python def Factorial(x): res = 1 for i in xrange(2, x + 1): res *= i return res print Factorial(6) #Lazy Python programmer def fact(x): return x > 1 and x * fact(x - 1) or 1 print fact(6) #Lazier Python programmer f = lambda x: x and x * f(x - 1) or 1 print f(6) #Python expert programmer import operator as op import functional as f fact = lambda x: f.foldl(op.mul, 1, xrange(2, x + 1)) print fact(6) #Python hacker import sys @tailcall def fact(x, acc=1): if x: return fact(x.__sub__(1), acc.__mul__(x)) return acc sys.stdout.write(str(fact(6)) + '\n') #EXPERT PROGRAMMER import c_math fact = c_math.fact print fact(6) #ENGLISH EXPERT PROGRAMMER import c_maths fact = c_maths.fact print fact(6) #Web designer def factorial(x): #------------------------------------------------- #--- Code snippet from The Math Vault --- #--- Calculate factorial (C) Arthur Smith 1999 --- #------------------------------------------------- result = str(1) i = 1 #Thanks Adam while i <= x: #result = result * i #It's faster to use *= #result = str(result * result + i) #result = int(result *= i) #?????? result str(int(result) * i) #result = int(str(result) * i) i = i + 1 return result print factorial(6) #Unix programmer import os def fact(x): os.system('factorial ' + str(x)) fact(6) #Windows programmer NULL = None def CalculateAndPrintFactorialEx(dwNumber, hOutputDevice, lpLparam, lpWparam, lpsscSecurity, *dwReserved): if lpsscSecurity != NULL: return NULL #Not implemented dwResult = dwCounter = 1 while dwCounter <= dwNumber: dwResult *= dwCounter dwCounter += 1 hOutputDevice.write(str(dwResult)) hOutputDevice.write('\n') return 1 import sys CalculateAndPrintFactorialEx(6, sys.stdout, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) #Enterprise programmer def new(cls, *args, **kwargs): return cls(*args, **kwargs) class Number(object): pass class IntegralNumber(int, Number): def toInt(self): return new (int, self) class InternalBase(object): def __init__(self, base): self.base = base.toInt() def getBase(self): return new (IntegralNumber, self.base) class MathematicsSystem(object): def __init__(self, ibase): Abstract @classmethod def getInstance(cls, ibase): try: cls.__instance except AttributeError: cls.__instance = new (cls, ibase) return cls.__instance class StandardMathematicsSystem(MathematicsSystem): def __init__(self, ibase): if ibase.getBase() != new (IntegralNumber, 2): raise NotImplementedError self.base = ibase.getBase() def calculateFactorial(self, target): result = new (IntegralNumber, 1) i = new (IntegralNumber, 2) while i <= target: result = result * i i = i + new (IntegralNumber, 1) return result print StandardMathematicsSystem.getInstance(new (InternalBase, new (IntegralNumber, 2))).calculateFactorial(new (IntegralNumber, 6)) 

источник http://gist.github.com/25049

Для этого используется следующий код.

 #include  #include  int main() { int x, number, fac; fac = 1; printf("Enter a number:\n"); scanf("%d",&number); if(number<0) { printf("Factorial not defined for negative numbers.\n"); exit(0); } for(x = 1; x <= number; x++) { if (number >= 0) fac = fac * x; else fac=1; } printf("%d! = %d\n", number, fac); } 

Для больших чисел вы, вероятно, можете уйти с приблизительным решением, которое дает tgamma (n! = Gamma (n + 1)) из math.h. Если вам нужны еще большие цифры, они не будут вписываться в двойной, поэтому вместо этого вы должны использовать lgamma (естественный журнал функции гамма).

Если вы работаете где-то без полной C99 math.h, вы можете легко сделать это самостоятельно:

 double logfactorial(int n) { double fac = 0.0; for ( ; n>1 ; n--) fac += log(fac); return fac; } 

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

Еще один подход, чтобы плакат знал о другой технике. Многие рекурсивные решения также могут быть замечены, в результате чего таблица запросов заполняется, когда алгоритм работает, резко сокращая затраты на будущие вызовы (вроде как принцип компиляции .NET JIT, я думаю).

Пример в C (C был помечен так, я думаю, это то, что вы хотите), используя рекурсию

 unsigned long factorial(unsigned long f) { if (f) return(f * factorial(f - 1)); return 1; } printf("%lu", factorial(5)); 

Нам нужно начинать с 1 до предела, указанного n Начиная с 1*2*3...*n .

В c, я пишу это как функцию.

 main() { int n; scanf("%d",&n); printf("%ld",fact(n)); } long int fact(int n) { long int facto=1; int i; for(i=1;i<=n;i++) { facto=facto*i; } return facto; } тот main() { int n; scanf("%d",&n); printf("%ld",fact(n)); } long int fact(int n) { long int facto=1; int i; for(i=1;i<=n;i++) { facto=facto*i; } return facto; } , main() { int n; scanf("%d",&n); printf("%ld",fact(n)); } long int fact(int n) { long int facto=1; int i; for(i=1;i<=n;i++) { facto=facto*i; } return facto; } 

Простейшим и эффективным является суммирование логарифмов. Если вы используете Log10, вы получаете мощность и показатель степени.

ПСЕВДОКОД

 r=0 for i form 1 to n r=r+log(i)/log(10) print "result is:", 10^(r-floor(r)) ,"*10^" , floor(r) 

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

Простое решение:

 unsigned int factorial(unsigned int n) { return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n; } 

Я бы сделал это с заранее рассчитанной таблицей поиска, как сказал Джон. Это будет быстрее вычислять, чем итеративное или рекурсивное решение. Он полагается на то, как быстро n! растет, потому что наибольший n! вы можете рассчитать без переполнения unsigned long long (максимальное значение 18 446 744 073 709 551 615) составляет всего 20! , поэтому вам нужен массив с 21 элементом. Вот как это выглядело бы в c:

 long long factorial (int n) { long long f[22] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000, 20922789888000, 355687428096000, 6402373705728000, 121645100408832000, 2432902008176640000, 51090942171709440000}; return f[n]; } 

Посмотреть на себя!

 **I used this code for Factorial:** #include int main(){ int i=1,f=1,n; printf("\n\nEnter a number: "); scanf("%d",&n); while(i<=n){ f=f*i; i++; } printf("Factorial of is: %d",f); getch(); } в **I used this code for Factorial:** #include int main(){ int i=1,f=1,n; printf("\n\nEnter a number: "); scanf("%d",&n); while(i<=n){ f=f*i; i++; } printf("Factorial of is: %d",f); getch(); } 
Давайте будем гением компьютера.