1.适用范围:幂的底数为long数,指数为int数,如13^3,65536^4,1048576^64,1073741824^256
2.思路:
2.1.大数转为01串的byte数组->13=1101
2.2.乘法的本质加法->2*3=2+2+2
2.3.乘法的一个因子转为基于2的多项式结构,将计算复杂度从指数级降为对数级->3*5=3*(2^0+2^2)
3.性能分析:与BigInteger性能相比,20+大整数,8+幂数相差30ms(i5-5200+16G+64bit环境)
/**
* 描述:getBit 返回实际的01串
* @param a
* @return
* @CreateOn 2023年3月12日 上午11:18:06
* @author chun_chang
*/
public static byte[] getBit(long a) {
String bs = Long.toBinaryString(a);
int l = bs.length();
byte[] b = new byte[l];
for (int i = l - 1; i >= 0; i--) {
b[i] = bs.charAt(i) == '1' ? (byte) 1 : (byte) 0;
}
return b;
}
/**
* 描述:add 01数加法
* @param a 0,1
* @param b 0,1
* @param o 前一步加法是否产生进位
* @return 返回01串
* @CreateOn 2023年3月12日 上午10:04:51
* @author chun_chang
*/
public static byte[] add(byte a, byte b, boolean o) {
byte[] c = new byte[2];
if (a == (byte) 1 && b == (byte) 1) {
c[0] = (byte) 1;
c[1] = o ? (byte) 1 : (byte) 0;
return c;
}
if (a == (byte) 0 && b == (byte) 0) {
c[0] = (byte) 0;
c[1] = o ? (byte) 1 : (byte) 0;
return c;
}
if (o) {// 01,10
c[0] = (byte) 1;
c[1] = (byte) 0;
} else {
c[1] = (byte) 1;
}
return c;
}
/**
* 描述:add 两个01数组相加
* @param a 01数组
* @param b 01数组
* @return 返回01串
* @CreateOn 2023年3月12日 上午10:59:10
* @author chun_chang
*/
public static byte[] add(byte[] a, byte[] b) {
/* 1.交换数组,确保a的长度大于b */
int l1 = a.length;
int l2 = b.length;
if (l1 < l2) {// 让a为长数组,b为短数组
byte[] c = new byte[l1];
System.arraycopy(a, 0, c, 0, a.length);
a = b;
b = c;
l1 = a.length;
l2 = b.length;
}
int j = l1 - l2;
byte[] c = new byte[l1 + 1];//返回值
boolean o = false;
int i = c.length - 1 - j;
while (i > 0) {//运算次数
byte[] t = add(a[j + i - 1], b[i - 1], o);
c[i + j] = (byte) t[1];
o = t[0] == (byte) 1;
i--;
if (i == 0 && o) {
c[i + j] = (byte) 1;
}
}
if (j != 0) {
if(c[j] == (byte) 1) {// 未参与计算部分产生了进位
byte[] g = new byte[j];
System.arraycopy(a, 0, g, 0, g.length);
o = true;
i = g.length - 1;
while (o) {
byte[] t = add(i == -1 ? (byte) 0 : g[i], (byte) 1, false);//g已经计算完成时,仍需要进位
o = t[0] == (byte) 1;
if (o) {
c[j] = (byte) 0;
} else {
c[j] = (byte) 1;
if(i > 0) {
System.arraycopy(g, 0, c, 1, i);
}
}
j--;
i--;
}
} else {
System.arraycopy(a, 0, c, 1, j);
}
}
if (c[0] == (byte) 0) {//未产生进位,回退至原始数据长度
byte[] r = new byte[c.length - 1];
System.arraycopy(c, 1, r, 0, r.length);
c = r;
}
return c;
}
/**
* 描述:pow 若计算8字节以上的幂数,需使用BigInteger
* @param a 底数
* @param e 指数
* @return
* @CreateOn 2023年3月12日 上午9:42:19
* @author chun_chang
*/
public static byte[] pow(long a, int e) {
byte[] b0 = getBit(a);
byte[] t = b0;// 临时变量---每次左移一位结果
byte[] t0 = b0;// 临时变量---一次幂乘结果---2^0+2^1+...+2^n=a
byte[] t1 = {};// 临时变量---每次迭代相加结果
int i = e;
while (i > 1) {
if (b0[b0.length - 1] == (byte) 1) {
t1 = add(t0, t1);
}
for (int j = 1; j < b0.length; j++) {// 计算a的2^n次方次相加结果
t = append(t, (byte) 0);// 每次乘2即相当于左移一位
if (b0[b0.length - 1 - j] == (byte) 1) {
t1 = add(t1, t);
}
}
t = t1;
t0 = t1;
t1 = new byte[]{ (byte) 0 };
i--;
}
t0 = convertByteArr(t0);//处理t1数组(01数)为真实byte[]
return t0;
}
/* 99.工具类 ********************************************/
public static byte[] append(byte[] a, byte b) {
if (a == null) {
return new byte[] { b };
}
int l = a.length;
byte[] r = new byte[l + 1];
System.arraycopy(a, 0, r, 0, l);
r[l] = b;
return r;
}
/**
* 描述:convertByteArr 01串数组转为真实byte[]
* @param a
* @return
* @CreateOn 2023年3月18日 上午9:05:39
* @author chun_chang
*/
public static byte[] convertByteArr(byte[] r) {
int l = r.length / 8 + (r.length % 8 == 0 ? 0 : 1);
byte[] r0 = new byte[l];//最后结果的真实bit位,多一字节,防止出现负数
byte[] r1 = new byte[l * 8];//扩展r为8的倍数
if(r.length % 8 == 0) {
r1 = r;
} else {
System.arraycopy(r, 0, r1, r1.length - r.length, r.length);
}
int i = 0;
while (i < r1.length / 8) {// 1111101
int k1 = 1;
byte t0 = (byte) 0;
for (int j = 7; j >= 0; j--) {
t0 += r1[8 * i + j] == (byte) 0 ? (byte) 0 : (byte) k1;
k1 *= 2;
}
r0[i] = t0;
i++;
}
byte[] r2 = new byte[r0.length + 1];
System.arraycopy(r0, 0, r2, 1, r0.length);
return r2;
}
public static void printByte(byte[] a) {
for (int i = 0; i < a.length; i++) {
byte b = a[i];
switch (b) {
case (byte) 1: System.out.print("1"); break;
case (byte) 0: System.out.print("0"); break;
default: break;
}
if (i != 0 && (a.length - i - 1) % 4 == 0 && i != a.length - 1) {
System.out.print("-");
}
}
System.out.println();
}
public static void main(String[] args) {
try {
long s = System.currentTimeMillis();
long a = 65536;// 65536---1048576---536870912---1073741824
int e = 256;
byte[] t1 = pow(a, e);
BigInteger bi = new BigInteger(t1);
System.out.println(String.format("耗时:%sms,%s^%s = %s", (System.currentTimeMillis() - s), a, e, bi));
long s1 = System.currentTimeMillis();
BigInteger b1 = BigInteger.valueOf(a);
BigInteger b2 = b1.pow(e);
System.out.println(String.format("耗时:%sms,%s^%s = %s", (System.currentTimeMillis() - s1), a, e, b2));
} catch (Exception e) {
e.printStackTrace();
}
}
耗时:27ms,536870912^256 = 702567101168536800922438590478865377668017001719915936579448912372598510715744763501882384612611566959117382494034312459455139914468038639460450383968644187276540204267413191969851320248492054104829090392640235960372015528898953417931025961211318901284945592338652387148889380139477673159673166984480858462104241873595434916008973279232690529636443623781982429995789170528351897122958739299052588215875549040296539813258471962309855251445352165360083482705227628564019875799210353202107711165274645247422723960748358673075052124925743656271067433352584177595131955952228868008409462423993636901021191146005210485725746249697492833141029213005140068829544325079486203500595980681399888021767822418563636109620918528346475469919357732436856244774953025784520910440245715254877697294968137714784970423847899034933148707338363052237617887197809531083256573604655618285407846288242153322994102834454883804418346444387462456790915102195175112593267832744876992469909478389663089430284854465913193931668535566593259529740689983148992706222437314956585372122129300992709406835892917374132958196105937002075215338312971490288354904725455748883750521542061490602682986125493092600841256535661692898466404805288388366665776276054099173372626748739933959132329871224658351267277850226392896225632861028885048664859392189984074814039827506368730257825656963203130339656565366099380135540718477596064143922571054209027700332797453309531061808314919329526622785778002738118608964351032592464408805847153207590853628353829683860223642868588852146970087883145237207403702297871836567968045497844960690660791494499997942130835795684443402861731108217771212163176237553923239702728600972947986460321978156507413727675962636506415822081344795767176509895667069969784352272563970900203401353241744099434703372080560349033093647680927506283666689457225189459896651540255824273932131306103174535680085257809209287122497227607986097049809908690596914837170777097789610579137508463360958989558526445443233014342065768862001587066902201545763318304941507767877856847648343871533710666108369002436748447879531979060305657642555847652329531745882539086858722020041727380861290865588040797570576462622422904384833884254746498287728246533422882094709638340559241216
耗时:0ms,536870912^256 = 702567101168536800922438590478865377668017001719915936579448912372598510715744763501882384612611566959117382494034312459455139914468038639460450383968644187276540204267413191969851320248492054104829090392640235960372015528898953417931025961211318901284945592338652387148889380139477673159673166984480858462104241873595434916008973279232690529636443623781982429995789170528351897122958739299052588215875549040296539813258471962309855251445352165360083482705227628564019875799210353202107711165274645247422723960748358673075052124925743656271067433352584177595131955952228868008409462423993636901021191146005210485725746249697492833141029213005140068829544325079486203500595980681399888021767822418563636109620918528346475469919357732436856244774953025784520910440245715254877697294968137714784970423847899034933148707338363052237617887197809531083256573604655618285407846288242153322994102834454883804418346444387462456790915102195175112593267832744876992469909478389663089430284854465913193931668535566593259529740689983148992706222437314956585372122129300992709406835892917374132958196105937002075215338312971490288354904725455748883750521542061490602682986125493092600841256535661692898466404805288388366665776276054099173372626748739933959132329871224658351267277850226392896225632861028885048664859392189984074814039827506368730257825656963203130339656565366099380135540718477596064143922571054209027700332797453309531061808314919329526622785778002738118608964351032592464408805847153207590853628353829683860223642868588852146970087883145237207403702297871836567968045497844960690660791494499997942130835795684443402861731108217771212163176237553923239702728600972947986460321978156507413727675962636506415822081344795767176509895667069969784352272563970900203401353241744099434703372080560349033093647680927506283666689457225189459896651540255824273932131306103174535680085257809209287122497227607986097049809908690596914837170777097789610579137508463360958989558526445443233014342065768862001587066902201545763318304941507767877856847648343871533710666108369002436748447879531979060305657642555847652329531745882539086858722020041727380861290865588040797570576462622422904384833884254746498287728246533422882094709638340559241216