1. 程式人生 > >n的階乘會溢位?解決超大數字階乘溢位問題。

n的階乘會溢位?解決超大數字階乘溢位問題。

package demo;

/**
 * Created by fx.
 */

    public class BigInteger
    {
        /**
         * 計算進位
         * @param bit	 陣列
         * @param pos 用於判斷是否是陣列的最高位
         */
        private void carry(int[] bit, int pos)
        {
            int i ,carray = 0;
            for(i = 0 ; i<= pos ;i++)//從0到pos逐位檢查是否需要進位
            {
                bit[i] += carray;//累加進位
                if(bit[i] <= 9)	 //小於9不進位
                {
                    carray = 0;
                }
                else if(bit[i] >9 && i 9 && i >= pos)//大於9,且是最高位
                {
                    while(bit[i] > 9)//迴圈向前進位
                    {
                        carray = bit[i]/10;//計算進位值
                        bit[i] = bit[i] % 10;//當前的第一位數
                        i ++ ;
                        bit[i] = carray;//在下一位儲存進位值
                    }
                }
            }
        }

        /**
         * 大整數階乘
         * @param bigInteger 所計算的大整數
         */
        private  void bigFactorial(int bigInteger)
        {
            int pos =0;//
            int digit;//資料長度
            int a , b ;
            int m = 0 ;//統計輸出位數
            int n  = 0 ;//統計輸出行數
            double sum = 0;//階乘位數
            for(a = 1 ; a <= bigInteger ; a ++)//計算階乘位數
            {
                sum += Math.log10(a);
            }
            digit = (int)sum + 1;//資料長度

            int[] fact = new int[digit];//初始化一個數組
            fact[0]  = 1;//設個位為 1

            for(a = 2 ; a <= bigInteger ; a++ )//將2^bigInteger逐個與原來的積相乘
            {
                for(b = digit-1 ; b >= 0 ; b--)//查詢最高位{}
                {
                    if( fact[b]  !=  0 )
                    {
                        pos = b ;//記錄最高位
                        break;
                    }
                }

                for(b = 0; b <= pos ; b++)
                {
                    fact[b] *= a ;//每一位與i乘
                }
                carry(fact,pos);
            }

            for(b = digit-1 ; b >= 0 ; b --)
            {
                if(fact[b] != 0)
                {
                    pos = b ;//記錄最高位
                    break;
                }
            }
            System.out.println(bigInteger +"階乘結果為:");
            for(a = pos ; a >= 0 ; a --)//輸出計算結果
            {
                System.out.print(fact[a]);
                m++;
                if(m % 5 == 0)
                {
                    System.out.print(" ");
                }
                if(40 == m )
                {
                    System.out.println("");
                    m = 0 ;
                    n ++;
                    if(10 == n )
                    {
                        System.out.print("\n");
                        n = 0;
                    }
                }
            }
            System.out.println("\n"+"階乘共有: "+(pos+1)+" 位");

        }

        public void doBigFactorial(int bigInteger)
        {
            int timeBegin=(int) System.currentTimeMillis();
            this.bigFactorial(bigInteger);
            int timeFinishi=(int) System.currentTimeMillis();
            int time = timeFinishi-timeBegin;
            System.out.println("計算耗時: " + time +"毫秒" );
        }

        public static void main(String[] args)
        {
            BigInteger bi = new BigInteger();
            bi.doBigFactorial(100000);
        }
    }