Wie kann ich ein Programm schreiben, um die Fakultät einer natürlichen Zahl zu finden?
Dies funktioniert für die Fakultät (wenn auch eine sehr kleine Teilmenge) von positiven ganzen Zahlen:
unsigned long factorial(unsigned long f)
{
if ( f == 0 )
return 1;
return(f * factorial(f - 1));
}
printf("%i", factorial(5));
Aufgrund der Art Ihres Problems (und des von Ihnen bekannten Niveaus) basiert diese Lösung eher auf dem Konzept der Lösung dieses Problems als auf einer Funktion, die in der nächsten "Permutation Engine" verwendet wird.
Hiermit werden Fakultäten für nicht negative ganze Zahlen [*] bis zu ULONG_MAX berechnet, die so viele Ziffern enthalten, dass es unwahrscheinlich ist, dass Ihr Computer eine ganze Menge mehr speichern kann, selbst wenn er Zeit hat, diese zu berechnen. Verwendet die GNU Multiple Precision Library, mit der Sie eine Verknüpfung herstellen müssen.
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
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);
}
Beispielausgabe:
$ make factorial CFLAGS="-L/bin/ -lcyggmp-3 -pedantic" -B && ./factorial
cc -L/bin/ -lcyggmp-3 -pedantic factorial.c -o factorial
100
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
[*] Wenn du etwas anderes als "Zahl" meinst, musst du genauer sein. Mir sind keine anderen Zahlen bekannt, für die die Fakultät definiert ist, obwohl Pascal sich bemüht hat, die Domäne durch Verwendung der Gamma-Funktion zu erweitern.
Warum es in C machen, wenn man in Haskell machen kann :
Freshman Haskell-Programmierer
fac n = if n == 0
then 1
else n * fac (n-1)
Sophomore Haskell-Programmierer am MIT .__ (studierte als Neuling)
fac = (\(n) ->
(if ((==) n 0)
then 1
else ((*) n (fac ((-) n 1)))))
Junior Haskell Programmierer (Anfänger Peano-Spieler)
fac 0 = 1
fac (n+1) = (n+1) * fac n
Ein weiterer Junior-Haskell-Programmierer (Lesen Sie, dass n + k Muster "ein ekelhafter Teil von Haskell" 1 Sind und sich der "Ban n + k Muster" -Bewegung [2] anschließen.)
fac 0 = 1
fac n = n * fac (n-1)
Senior Haskell-Programmierer .__ (gewählt für Nixon Buchanan Bush - "lehnt sich nach rechts")
fac n = foldr (*) 1 [1..n]
Ein anderer hochrangiger Haskell-Programmierer. (Gewählt für McGovern Biafra Nader - "lehnt sich nach links")
fac n = foldl (*) 1 [1..n]
Noch ein älterer Haskell-Programmierer. (Lehnte sich so weit nach rechts, dass er wieder links war!)
-- using foldr to simulate foldl
fac n = foldr (\x g n -> g (x*n)) id [1..n] 1
Protokollierung des Programmierers von Haskell (Nimmt täglich Ginkgo Biloba)
facs = scanl (*) 1 [1..]
fac n = facs !! n
Sinnloser (ähm) "Punkte-freier" Haskell-Programmierer (Studierte in Oxford)
fac = foldr (*) 1 . enumFromTo 1
Iterativer Haskell-Programmierer (Früherer Pascal-Programmierer)
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 i n d = until d n i
Iterativer Einzeiler-Haskell-Programmierer (Früherer APL- und C-Programmierer)
fac n = snd (until ((>n) . fst) (\(i,m) -> (i+1, i*m)) (1,1))
Haskell-Programmierer akkumulieren (Aufbau auf einen schnellen Höhepunkt)
facAcc a 0 = a
facAcc a n = facAcc (n*a) (n-1)
fac = facAcc 1
Weitergabe-Haskell-Programmierer (RABBITS in frühen Jahren angehoben, dann nach New Jersey gezogen)
facCps k 0 = k 1
facCps k n = facCps (k . (n *)) (n-1)
fac = facCps id
Pfadfinder-Haskell-Programmierer .__ (mag Knoten binden; immer "ehrfürchtig"; er Gehört zur Kirche des kleinsten Fixpunkts [8])
y f = f (y f)
fac = y (\f n -> if (n==0) then 1 else n * f (n-1))
Kombinatorischer Haskell-Programmierer (Lehnt Variablen ab, wenn nicht Verschleierung; Das ganze Currying ist nur eine Phase, obwohl es selten behindert)
s f g x = f x (g x)
k x y = x
b f g x = f (g x)
c f g x = f x g
y f = f (y f)
cond p f g x = if p x then f x else g x
fac = y (b (cond ((==) 0) (k 1)) (b (s (*)) (c b pred)))
List-Encoding-Haskell-Programmierer
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
Interpretierender Programmierer von Haskell ("Traf nie eine Sprache", die er nicht mochte)
-- 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 m n) = prjFun (eval env m) (eval env n)
eval env (Abs x m) = Fun (\v -> eval ((x,v) : env) m)
eval env (Rec x m) = 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)))
Statischer Haskell-Programmierer (Er macht es mit dem Unterricht, er hat den Grundstein Jones! Nach Thomas Hallgrens "Spaß mit funktionalen Abhängigkeiten" [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 a b c | a b -> c where
add :: a -> b -> c
instance Add Zero b b
instance Add a b c => Add (Succ a) b (Succ c)
-- multiplication, a la Prolog
class Mul a b c | a b -> c where
mul :: a -> b -> c
instance Mul Zero b Zero
instance (Mul a b c, Add b c d) => Mul (Succ a) b d
-- factorial, a la Prolog
class Fac a b | a -> b where
fac :: a -> b
instance Fac Zero One
instance (Fac n k, Mul (Succ n) k m) => Fac (Succ n) m
-- try, for "instance" (sorry):
--
-- :t fac four
Beginn des Haskell-Programmierers für Hochschulabsolventen. (Die Absolventenausbildung befreit in der Regel von unbedeutenden Problemen .__ über beispielsweise die Effizienz hardwarebasierter Ganzzahlen).
-- the natural numbers, a la Peano
data Nat = Zero | Succ Nat
-- iteration and some applications
iter z s Zero = z
iter z s (Succ n) = s (iter z s n)
plus n = iter n Succ
mult n = iter Zero (plus n)
-- primitive recursion
primrec z s Zero = z
primrec z s (Succ n) = s n (primrec z s n)
-- two versions of factorial
fac = snd . iter (one, one) (\(a,b) -> (Succ a, mult a b))
fac' = primrec one (mult . Succ)
-- for convenience and testing (try e.g. "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 c n [] = n
fold c n (x:xs) = c x (fold c n xs)
prod = fold (*) 1
-- (curried, boolean-based, list) unfold and an application
unfold p f g x =
if p x
then []
else f x : unfold p f g (g x)
downfrom = unfold (==0) id pred
-- hylomorphisms, as-is or "unfolded" (ouch! sorry ...)
refold c n p f g = fold c n . unfold p f g
refold' c n p f g x =
if p x
then n
else c (f x) (refold' c n p f g (g x))
-- several versions of factorial, all (extensionally) equivalent
fac = prod . downfrom
fac' = refold (*) 1 (==0) id pred
fac'' = refold' (*) 1 (==0) id pred
Haskell-Programmierer, kartesisch veranlagt. (Bevorzugt griechisches Essen, vermeidet das scharfe indische Zeug; Inspiriert von Lex Augusteijns „Sorting Morphisms“ [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 f g = cata g . ana f
hylo' f (n,c) = either (const n) (c . pair (id, hylo' f (c,n))) . f
pair (f,g) (x,y) = (f x, g y)
-- several versions of factorial, all (extensionally) equivalent
fac = prod . downfrom
fac' = hylo uncount (1, mult)
fac'' = hylo' uncount (1, mult)
Ph.D. Haskell-Programmierer (Hat so viele Bananen gegessen, dass seine Augen herauskamen, jetzt braucht er neue Linsen!)
-- 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 z s Zero = z
nelim z s (Succ n) = s n
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 a b = Nil | Cons a b deriving Show
instance Functor (L a) where
fmap f = lelim Nil (\a b -> Cons a (f b))
lelim n c Nil = n
lelim n c (Cons a b) = c a b
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 f x = f x x
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 (g x)
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 m f
-- explicit products and their functorial action
data Prod e c = Pair c e
outl (Pair x y) = x
outr (Pair x y) = y
fork f g x = Pair (f x) (g x)
instance Functor (Prod e) where
fmap g = fork (g . outl) outr
-- comonads, the categorical "opposite" of monads
class Functor n => Comonad n where
extr :: n a -> a
dupl :: n a -> n (n a)
instance Comonad (Prod e) where
extr = outl
dupl = fork id outr
-- generalized catamorphisms, zygomorphisms and paramorphisms
gcata :: (Functor f, Comonad n) =>
(forall a. f (n a) -> n (f a))
-> (f (n c) -> 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 f n)) = 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
Tenured Professor .__ (unterrichtet Haskell Neulingen)
fac n = product [1..n]
Dank an Christoph, eine C99-Lösung, die für einige "Zahlen" funktioniert:
#include <math.h>
#include <stdio.h>
double fact(double x)
{
return tgamma(x+1.);
}
int main()
{
printf("%f %f\n", fact(3.0), fact(5.0));
return 0;
}
produziert 6.000000 120.000000
Bei großen n können Sie auf einige Probleme stoßen und Sie können die Annäherung von Stirling verwenden:
Welches ist:
Wenn Ihr Hauptziel eine interessant aussehende Funktion ist:
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;
}
(Nicht als Algorithmus für den tatsächlichen Einsatz empfohlen.)
In C99 (oder Java) würde ich die Faktorfunktion iterativ folgendermaßen schreiben:
int factorial(int n)
{
int result = 1;
for (int i = 2; i <= n; i++)
{
result *= i;
}
return result;
}
C ist keine funktionale Sprache und Sie können sich nicht auf die Optimierung des Anrufs verlassen. Verwenden Sie also keine Rekursion in C (oder Java), es sei denn, Sie müssen dies tun.
Nur weil Factorial oft als erstes Beispiel für Rekursion verwendet wird, bedeutet dies nicht, dass Sie Rekursion benötigen, um es zu berechnen.
Dies wird automatisch überlaufen, wenn n zu groß ist, wie dies in C (und Java) der Fall ist.
Wenn die Zahlen, die int darstellen kann, für die zu berechnenden Fakultäten zu klein sind, wählen Sie einen anderen Zahlentyp. long lang, wenn es nur ein bisschen größer sein muss, float oder double, wenn n nicht zu groß ist, und es Ihnen nichts ausmacht, wenn Sie die genauen Werte von wirklich großen Fakultäten wollen.
eine rekursive Version:
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);
}
Hier ist ein C-Programm, das die BIGNUM-Implementierung von OPENSSL verwendet und daher für Studenten nicht besonders nützlich ist. (Natürlich ist die Annahme eines BIGNUM als Eingabeparameter verrückt, aber hilfreich, um die Interaktion zwischen BIGNUMs zu demonstrieren.).
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <openssl/crypto.h>
#include <openssl/bn.h>
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;
}
Dieses Testprogramm zeigt, wie Sie eine Zahl für die Eingabe erstellen und was mit dem Rückgabewert zu tun ist:
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;
}
Mit gcc zusammengestellt:
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))
quelle http://Gist.github.com/25049
Dazu verwenden Sie den folgenden Code.
#include <stdio.h>
#include <stdlib.h>
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);
}
Ich glaube nicht, dass ich dies in den meisten Fällen anwenden würde, aber eine bekannte Praxis, die immer weniger verbreitet wird, ist das Nachschlagen einer Tabelle. Wenn wir nur mit integrierten Typen arbeiten, ist der Speicherhit klein.
Nur ein anderer Ansatz, um das Poster auf eine andere Technik aufmerksam zu machen. Viele rekursive Lösungen können auch gespeichert werden, wodurch eine Nachschlagetabelle ausgefüllt wird, wenn der Algorithmus ausgeführt wird, wodurch die Kosten für zukünftige Aufrufe drastisch gesenkt werden (wie das Prinzip der .NET JIT-Kompilierung, denke ich).
Bei großen Zahlen können Sie wahrscheinlich mit einer ungefähren Lösung davonkommen, die tgamma
Ihnen (n! = Gamma (n + 1)) von math.h gibt. Wenn Sie noch größere Zahlen wünschen, passen diese nicht in ein Doppel, daher sollten Sie stattdessen lgamma
(natürliches Protokoll der Gamma-Funktion) verwenden.
Wenn Sie irgendwo ohne eine vollständige C99 math.h arbeiten, können Sie diese Art von Dingen problemlos selbst ausführen:
double logfactorial(int n) {
double fac = 0.0;
for ( ; n>1 ; n--) fac += log(fac);
return fac;
}
Einfache Lösung:
unsigned int factorial(unsigned int n)
{
return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
}
Am einfachsten und effizientesten ist es, Logarhitmen zusammenzufassen. Wenn Sie Log10 verwenden, erhalten Sie Leistung und Exponent.
Pseudocode
r=0
for i form 1 to n
r=r+log(i)/log(10)
print "result is:", 10^(r-floor(r)) ,"*10^" , floor(r)
Möglicherweise müssen Sie den Code hinzufügen, damit der ganzzahlige Teil nicht zu sehr ansteigt und somit die Genauigkeit verringert. Das Ergebnis ist jedoch auch für sehr große Fakultäten in Ordnung.
Wir müssen von 1
bis zum angegebenen Limit sagen, sagen wir n
. Beginnen Sie mit 1*2*3...*n
.
In c schreibe ich es als Funktion.
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;
}
Beispiel in C (C wurde mit Tags versehen, ich denke, das ist, was Sie wollen) mit Rekursion
unsigned long factorial(unsigned long f)
{
if (f) return(f * factorial(f - 1));
return 1;
}
printf("%lu", factorial(5));
Ich würde das mit einer vorberechneten Nachschlagetabelle machen, wie John sagte. Dies wäre schneller zu berechnen als eine iterative oder rekursive Lösung. Es hängt davon ab, wie schnell n!
wächst, denn das größte n! Sie können berechnen, ohne einen unsigned long long
zu überschreiten (maximaler Wert von 18.446.744.073.709.551.615). Dies ist nur 20!
, sodass Sie nur ein Array mit 21 Elementen benötigen. So würde es in c aussehen:
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<stdio.h>
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();
}