天天看点

完全输出a的n次幂的结果(不用科学计数法表示法)

看《最强大脑》某期 中徳pk赛中 德国选手“次方哥” 秒算99的17次方,结果是34位数,当时非常震惊。他坦言心算分为记忆部分和运算部分,由于记忆部分出错,结果错了一位数,但不管是如何算出来的,就算是完全背出来的也挺厉害的,毕竟11~99的1~20次方(次方哥的秒出范围)也有89*20=1680中组合,并且有很多结果都有几十位,靠记忆的话不太容易。

一般的计算器输出a的n次幂的结果时多是用科学计数法表示的,可以运行微软系统自带的计算器calc.exe 。

例如2^1024=1.797693134862315907729305190789e+308

2^10240=3.5249714121083826571348148398003e+3082

2^102400=溢出

99^17=8.4294319338392688324856426786417e+33(次方哥将倒数最后的一个4记成了5)

99^20=8.1790693759723087088919866054434e+39

2015^1124=1.0119445978051020448707773176553e+3714

下面贴出源码:

package com.express;

import java.util.Date;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
        System.out.println(calc(,));
        System.out.println(calc(,));
        //System.out.println(calc(999999,11621));
        //System.out.println(calc(2,102400));

    }
    /**
     * 求 a的N次方(理论上a可以是long类型19位数,N只能是int类型10位数)
     * 建议N最好是不超过6位数(N为6位数时执行时间有时会超过5秒)
     * long 最大值是19位数,所以要保证数组中的每个数与基数a相乘时不能溢出,
     * 所以数组中数的位数为17-aLength,数组的维数只能是int类型,十位数
     * 注意:输出时1030%1000 的结果应该取030而不是30,即要取满d位
     * 思路:
     * 1.先分别计算数组中每个数乘上基数后的值
     * 2.然后循环将低位的数产生的进位累加到高位,如果最高位后还有进位,
     * 再对最高位的数进行d位分组
     * @param a 基数
     * @param N 次方数
     * @return 字符串格式的计算结果
     */
    public static String calc(long a,int N)
    {
        if(a==) return "1"; 
        System.out.println("计算"+a+"的"+N+"次幂:");
        long startTime = new Date().getTime();
        int aLengh = Long.toString(a).length();
        //17的含义:
        //如果基数是5位数乘以12位数最大是17位数,加上进位后最多18位数,
        //不会超出long类型19位数,故取17保险
        //在每次计算时是用基数a分别乘上数组中的每个数
        int d = -aLengh;//数组中每个数的位数
        int maxDim = aLengh*N/d+;//数组最大维数,为了防止越界溢出+2
        System.out.println("数组每个数的位数="+d+",最大数组维数="+maxDim+
                ",最高共"+aLengh*N+"位数");
        long[] r = new long[maxDim];
        long group =(long) Math.pow(, d);//10的d次方,分组整除数
        System.out.println("分组整除数="+group);
        int top = ;//最高的数组下标位,计算的结果占的最高的数组下标
        r[]=;
        for(int i=;i<N;i++){
            //先分别计算数组中每个数乘上基数后的值
            for(int j=;j<=top;j++)
            {
                r[j] *= a;
            }
            //然后循环将低位的数产生的进位累加到高位,如果最高位后还有进位,
            //再对最高位的数进行d位分组
            long temp = r[];//初始最低位开始
            for(int j=;j<=top;j++){
                r[j]=temp%group;//保留d位
                //将进位累加到高位,此处易发生数组边界越界,所以维数+2
                temp=r[j+]+temp/group;
                //如果是最高位后的进位大于0,则再进行d位分组
                if(j==top&&temp>)
                {
                    top++;
                    r[top] = temp%group;
                    while(temp/group>){
                        temp /= group;
                        top++;
                        r[top]=temp%group;
                    }
                    break;
                }
            }
            //System.out.println("N="+i+"时:"+output(r,top));
        }
        //输出结果
        long dt = new Date().getTime()-startTime;
        System.out.println("实际数组维数:"+(top+)+",实际的结果位数:"+(top*d+Long.toString(r[top]).length()));
        System.out.println("共执行毫秒数:"+dt);
        return output(r,top,d);
    }
    private static String output(long[] r,int top,int d)
    {
        StringBuilder result = new StringBuilder();
        for(int i=top;i>=;i--)
        {
            if(i!=top) result.append(" ");
            //注意输出时不够d位的要补0
            String format = "%"+d+"d";
            if(i==top)
                result.append(String.format(format, r[i]));
            else
                result.append(String.format(format, r[i]).replace(" ", "0"));
            if(i%==) result.append("\r\n");
        }
        return result.toString();
    }
}
           

计算2的1024次幂:

数组每个数的位数=16,数组维数=66,最高共1024位数

分组整除数=10000000000000000

实际数组维数:19,实际的结果位数:309

共执行毫秒数:1

17976 9313486231590772 9305190789024733 6179769789423065 7273430081157732

6758055009631327 0847732240753602 1120113879871393 3576587897688144 1662249284743063

9474124377767893 4248654852763022 1960124609411945 3082952085005768 8381506823424628

8147391311054082 7237163350510684 5862982399472459 3847971630483535 6329624224137216

计算99的99次幂:

数组每个数的位数=15,数组维数=15,最高共198位数

分组整除数=1000000000000000

实际数组维数:13,实际的结果位数:198

共执行毫秒数:0

369 729637649726772 657187905628805 440595668764281

741102430259972 423552570455277 523421410650010 128232727940978 889548326540119

429996769494359 451621570193644 014418071060667 659301384999779 999159200499899

继续阅读