Created
April 9, 2016 14:11
-
-
Save WeZZard/3fee0549fb4b300f89f8aea630907ccd to your computer and use it in GitHub Desktop.
Factorial
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
postfix operator !! { } | |
public postfix func !! <I: UnsignedIntegerType>(x: I) -> UInt { | |
#if arch(x86_64) || arch(arm64) | |
precondition( | |
x.toUIntMax() < 21, | |
"Invalid input to compute a factorial(< 21 on 64-bit arch)." | |
) | |
#else | |
precondition( | |
x.toUIntMax() < 13, | |
"Invalid input to compute a factorial.(< 13 on 32-bit arch)" | |
) | |
#endif | |
var x: UInt = numericCast(x) | |
var b: UInt = 0 , c: UInt = 0 , fractorial: UInt = 0 | |
c = x - 1; | |
fractorial = 1; | |
while(c>0) { | |
fractorial = 0; | |
b = c; | |
while b > 0 { | |
if b & 1 != 0 { | |
fractorial += x; // p = p + N; | |
} | |
// if you would like to use double choose the alternative forms instead shifts | |
// the code is fast even! | |
// you can use the same tips on double or 64 bit int etc.... but you must... ;-) | |
b = b>>1; // b/=2; (b = b / 2;) ( b >> 1; a.s.r. is more efficent for int or long..!) | |
x = x<<1; // N += N; N = N + N; N = N * 2; (N <<=1; a.s.l. is more efficent for int or long..!) | |
} // end of: while(b>0) | |
x = fractorial; | |
c = c - 1; // c = c - 1; | |
} // end of: while(c > 0) | |
return fractorial | |
} | |
public postfix func !! <I: SignedIntegerType>(x: I) -> Int { | |
#if arch(x86_64) || arch(arm64) | |
precondition( | |
x.toIntMax() < 21, | |
"Invalid input to compute a factorial(< 21 on 64-bit arch)." | |
) | |
#else | |
precondition( | |
x.toIntMax() < 13, | |
"Invalid input to compute a factorial.(< 13 on 32-bit arch)" | |
) | |
#endif | |
var x: Int = numericCast(x) | |
var b: Int = 0 , c: Int = 0 , fractorial: Int = 0 | |
c = x - 1; | |
fractorial = 1; | |
while(c>0) { | |
fractorial = 0; | |
b = c; | |
while b > 0 { | |
if b & 1 != 0 { | |
fractorial += x; // p = p + N; | |
} | |
// if you would like to use double choose the alternative forms instead shifts | |
// the code is fast even! | |
// you can use the same tips on double or 64 bit int etc.... but you must... ;-) | |
b = b>>1; // b/=2; (b = b / 2;) ( b >> 1; a.s.r. is more efficent for int or long..!) | |
x = x<<1; // N += N; N = N + N; N = N * 2; (N <<=1; a.s.l. is more efficent for int or long..!) | |
} // end of: while(b>0) | |
x = fractorial; | |
c = c - 1; // c = c - 1; | |
} // end of: while(c > 0) | |
return fractorial | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment