Factorial growth and solutions and factorial growth solutions
Growth of factorial
Many programming books have introduced factorial. I believe that everyone, including me, can read it and never think about other problems in depth. For example, in the range of Integers (C #), how much can a factorial be calculated.
The following code is used for testing:
int total = 1; for (int i =
1
; i <= 20; i++) { total *= i; Console.WriteLine("{0}\t{1}",i,total); }
The result is as follows:
/// <Summary> // multiplication class, it can be used to count the Multiplication of less than of Int32.MaxValue /// </summary> public class Multiplication {# region Fields /// <summary> /// an array that saves the Multiplication result /// </summary> private int [] _ result = new int [4]; /// <summary> /// maximum bit of the multiplier /// </summary> private int _ topDigit = 3; /// <summary> /// maximum quilt multiplier /// </summary> public const int MaxMultiplier = Int32.MaxValue/9; # endregion Fields # region Properties // <summary> /// Obtain the Result enumerator, from high to low. /// </summary> public IEnumerable <int> result {get {return _ Result. skip (_ topDigit );}} # endregion Properties # region Public Methods # region Constructs // <summary> // use the multiplier of 1 to construct a Multiplication class // </summary> public Multiplication () {// initialize to 1 _ result [_ result. length-1] = 1 ;} /// <summary> /// use the specified multiplier to construct a multiplication class /// </summary> /// <param name = "multiplicand"> quilt multiplier </param> public multiplicatio N (int multiplicand): this () {Multiply (multiplicand );} # endregion Constructs # region Operators // <summary> // overload the multiplication operator /// </summary> /// <param name = "multiplication"> multiplication class </ param> // <param name = "multiplier"> multiplier, cannot be greater than 1/9 of Int32.MaxValue </param> // <returns> Multiplication class after Multiplication </returns> public static multiplication operator * (Multiplication, int multiplier) {return multiplication. multipl Y (multiplier );} /// <summary> /// implicitly convert the specified multiplier to a multiplication class /// </summary> /// <param name = "multiplicand"> multiplier </param >/// <returns> Multiplication class after conversion </returns> public static implicit operator Multiplication (int multiplicand) {return new Multiplication (multiplicand );} /// <summary> /// explicitly convert the multiplication class to int // </summary> /// <param name = "multiplication"> multiplication class </param >/// <returns> converted int </returns> public static explicit opera Tor int (Multiplication multiplication) {int value = 0; int digit = 1; var result = multiplication. _ result; for (int I = result. length-1; I> multiplication. _ topDigit-1; I --) {value + = result [I] * digit; digit * = 10;} return value ;} # endregion Operators // <summary> // perform multiplication with the specified multiplier /// </summary> /// <param name = "multiplier"> multiplier, it cannot be greater than one tenth of Int32.MaxValue </param> // <returns> the multiplication class after multiplication </ret Urns> public Multiplication Multiply (int multiplier) {Contract. assert (MaxMultiplier> multiplier); int digit = GetDigits (multiplier); // Add the number of digits to the multiplier for (int I = _ topDigit; I <_ result. length; I ++) {int d = GetDigits (_ result [I]); d + = _ result. length-I-1; // Add the number of digits of the permission. For example, 100 corresponds to two digits, and 1000 corresponds to three digits of digit + = d;} // expand one digit, hold the permission value digit + = 1; // if (digit> _ result. length) {var result = new int [digit]; // Valid number length int validLength = _ result. length-_ topDigit; Array. copy (_ result, _ topDigit, result, result. length-validLength, validLength); _ topDigit + = digit-_ result. length; _ result = result;} // calculate for (int I = _ topDigit; I <_ result. length; I ++) {_ result [I] * = multiplier;} Carry (); return this ;} # endregion Public Methods # region Private Methods // <summary> // carry // </summary> private vo Id Carry () {// from the first digit of the number of multiplier to the highest digit, Carry for (int I = _ result. length-1; I> _ topDigit-1; I --) {int carry = _ result [I]/10; _ result [I] = _ result [I] % 10; _ result [I-1] + = carry;} // carry in the highest bit of the multiplier for (int I = _ topDigit-1; I --) {int carry = _ result [I]/10; _ result [I] = _ result [I] % 10; if (0! = Carry) {_ result [I-1] + = carry;} else {break;} UpdateTopDigit ();} /// <summary> /// obtain the number of digits /// </summary> /// <param name = "number"> number </param> // <returns> number of digits </returns> private int GetDigits (int number) {return (int) Math. ceiling (Math. log10 (number);} // <summary> // update the highest bit // </summary> private void UpdateTopDigit () {_ topDigit = 0; for (int I = 0; I <_ result. length; I ++) {if (_ resu Lt [I]! = 0) {_ topDigit = I; break ;}}# endregion Private Methods}
The usage is also simple:
/// <Summary> /// calculate the factorial /// </summary> /// <param name = "n"> the factorial to be calculated </param> /// <returns> factorial result, number from high to low </returns> static IEnumerable <int> Factrial (int n) {var mul = new Multiplication (); for (int I = 2; I <= n; I ++) {mul * = I;} return mul. result ;}
Extension
As mentioned above, the calculation can only be greater than int. if you need to calculate a larger factorial for MaxValue 1/9, you cannot directly multiply each of the multiplier and the multiplier. Instead, you need to further refine the factorial, multiply and sum each of the multiplier in turn. For example, 11x11 = 10*11 + 1*11 = (10*10 + 10*1) + (1*10 + 1*1 ). Code implementation is not provided here.
In the same way, Division can also be converted into subtraction.
BigInteger Structure
So much is said above, but it is not. Starting from. Net Framework 4.0, The BigInteger structure is provided to represent any large integer. Theoretically, the value has no upper or lower boundary. I will not go into detail here. For details, refer to the BigInteger structure.
References
Mathematical thinking cultivation for programmers