Java大数运算
问题描述:计算 2^1000 的值
1、运算思路
1、首先计算结果肯定会超出系统提供的数据类型,不能采用常规数据类型处理。
2、采用字符串或者字符数组、集合表示
3、本体采用ArrayList集合来存储,在不确定数组长度时可能会产生一部分内存浪费
4、采用笔算常用的计算方式将大数分割成每一位进行单独运算,并处理好进位。
5、尽可能的缩小循环体执行次数
2、编码步骤
1、转化为4^5000次方计算
1、代码内容
//大循环需要执行5000次,整体执行7528246次
//同样将乘数换成8最后在乘一个2,也可以得到,而且更高效。
import java.util.ArrayList;
import java.util.List;
public class main01 {
public static void main(String[] args) {
long count = 0;
long startTime = System.currentTimeMillis();
String num1 = "2";
char[] a = num1.toCharArray();
List<Integer> list_source = new ArrayList<Integer>();
List<Integer> list_new = new ArrayList<Integer>();
for (int i = 0; i < a.length; i++) {
list_source.add(Integer.parseInt(a[i] + ""));
}
for (int j = 0; j < 5000; j++) {
int length = list_source.size();
int num = 0;
int temp = 0;
for (int i = 0; i < length; i++) {
count++; // 循环次数计算器
temp = list_source.get(length - 1 - i); // 将集合中的最后一个元素取出
temp = temp * 4; // 用该元素进行计算
num += temp; // 计算出的结果要加上上一个的进位
list_new.add(0, num % 10); // 将个位加入新的集合
num = num / 10; // 获取进位值
// System.out.println(num);
}
if (num != 0) { // 在循环退出后,处理最后的进位
list_new.add(0, num);
}
list_source.clear();
list_source.addAll(list_new);
list_new.clear();
}
long endTime = System.currentTimeMillis();
System.out.println("时间:" + (endTime - startTime));
System.out.println("循环次数:" + count);
for (Integer i : list_source) {
System.out.print(i);
}
}
}
2、输出结果显示
时间:1438
循环次数:7528246
39901262337615167697674843253671701676469936637723849097040178997058877660443893263839923368072389195798662258846418248543112982698827562235187571864192647915711460093587589053530493102532119791041100173836386623085017216921236209371018149732179249776180979789676018507883266515701243136618947805113824776130450193287748882093519743253970906445737076323388631551259281525673761521464457070183282952367912762917938927798821681921072535642129242854666788073051131299061206285360469938800671868633302918595546559331551212345164062815988396359214756491367524560074605770974503801668929162909301115859202829667843231469176278514190759538238555601653915471348888246124037515672651005456647578541420747605732786062856266482803248391343381148122839308684649277602497712294610414863984519223592500261985720483416681615211864640322536984576992511682625688123073477902974228512630222179491028406627640405863281915192929512020811691683132144089925734033030123841262008372844551817341801149212835713903822912110136502500812015039684523796118474236108889576145812790485096678443965414808946324753521693226067557412079606826394266987309245401126339874911016483561945621966582628807143755049537019714553875852866443198799753773321616737675676055286565550344547315145489568224588779467621723214846506583949626240395208356563931394951796329062516868271919725568260256370812566953298177381042095161765231647923971540244814088661166151738078639209206809946313166417344211826601807505646831079490788795430514910581020424621894643221506949651481550547972696596996681513875911293277243749138998558033144207402728866271634428623582796445967691694668880541928365702010145855496729101157269002201705975624778947857399081668692317614087918237971630291558354287239397456262918967566404162949964343716022778142456501811653634872441154951842835307431375451229809165809984922057260163071166616260203975351712468687077910818351246801689775052325287137297667038927440754586480188912493846508700801356054547675510752813453797272482074982821933437114101518196200493579760356543851906762564843908056605518816897910029353336779395993772483272626752787806746911602815273483755422110768451478998220372936439393163302970260988444739895429526138310936435365752400725554515447562730663222393622561585338963774402597287321537103279721069204595743115035894770492738893846175788531896434016102240644730992576338071478242736676787183512837467701021940543227830879181983196309308834672623313872062244499875939998453563464716046223725289150598271516350016399678472569230499762177920464488724347543236172714030936968117244659585707751246973112881073925244037927142057624723135025086676606540058195337301137114315011033455037798388259422675380299832362630343088015457301146379114901840660370609694227636630814648106638076924168072843527407823101279578001485707344392561806955949066640936737591737160475904437258240161485639102635896315248896597036923019409776054549443149376263189500819464230160996380911606833653899574282632126421372783023363548609585193418752
2、转化为 1024^1000次方计算
//主循环体执行1000,但将1024分割后会产生四组值需要对他们进行加和,还要保持进位和对齐,因此,循环次数会大部分浪费在元素加和计算上。
public class main03 {
static long count =0;
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
String num1 = "2";
int Multiplier = 1024;
char[] a = num1.toCharArray();
List<Integer> list_source = new ArrayList<Integer>(); // 源数据集合
List<Integer> list01 = new ArrayList<Integer>(); // 乘数集合
List<Integer> list02 = new ArrayList<Integer>(); // 乘数集合
List<Integer> list03 = new ArrayList<Integer>(); // 乘数集合
List<Integer> list04 = new ArrayList<Integer>(); // 乘数集合
List<Integer> list_new = new ArrayList<Integer>(); // 新数据集合
for (int i = 0; i < a.length; i++) {
list_source.add(Integer.parseInt(a[i] + ""));
}
//循环求乘方
for (int j = 0; j < 1000; j++) {
list01 = test(list_source, Multiplier % 10); // 不变
list02 = test(list_source, Multiplier / 10 % 10); // 最后填一个0
list03 = test(list_source, Multiplier / 100 % 10); // 最后天两个0
list04 = test(list_source, Multiplier / 1000); // 最后天三个0
// 对三个集合进行求和
list02.add(list02.size(), 0);
list03.add(list03.size(), 0);
list03.add(list03.size(), 0);
list04.add(list04.size(), 0);
list04.add(list04.size(), 0);
list04.add(list04.size(), 0);
// 补齐
int len = list04.size() - list03.size();
for (int i = 0; i < len; i++) {
list03.add(0, 0);
count ++; //循环次数计数器
}
len = list04.size() - list02.size();
for (int i = 0; i < len; i++) {
list02.add(0, 0);
count ++; //循环次数计数器
}
len = list04.size() - list01.size();
for (int i = 0; i < len; i++) {
list01.add(0, 0);
count ++; //循环次数计数器
}
// 集合求和
int length = list04.size();
int num = 0;
for (int i = 0; i < length; i++) {
count ++; //循环次数计数器
num = list01.get(length - 1 - i) + list02.get(length - 1 - i)
+ list03.get(length - 1 - i)
+ list04.get(length - 1 - i) + num;
list_new.add(0, num % 10);
num = num / 10;
}
if (num != 0) {
list_new.add(0, num);
}
// 循环乘方的话,需要对换。
list_source.clear();
list_source.addAll(list_new);
list_new.clear();
}
long endTime = System.currentTimeMillis();
System.out.println("时间:" + (endTime - startTime));
System.out.println("循环次数:"+count);
for(Integer i:list_source){
System.out.print(i);
}
}
private static List<Integer> test(List<Integer> list_source, int Multiplier) {
List<Integer> list_new = new ArrayList<Integer>();
int length = list_source.size();
int num = 0;
int temp = 0;
for (int i = 0; i < length; i++) {
count ++; //循环次数计数器
temp = list_source.get(length - 1 - i); // 将集合中的最后一个元素取出
temp = temp * Multiplier; // 用该元素进行计算
num += temp; // 计算出的结果要加上上一个的进位
list_new.add(0, num % 10); // 将个位加入新的集合
num = num / 10; // 获取进位值
}
if (num != 0) { // 在循环退出后,处理最后的进位
list_new.add(0, num);
}
return list_new;
}
}
2、结果显示
时间:1642
循环次数:7530338
39901262337615167697674843253671701676469936637723849097040178997058877660443893263839923368072389195798662258846418248543112982698827562235187571864192647915711460093587589053530493102532119791041100173836386623085017216921236209371018149732179249776180979789676018507883266515701243136618947805113824776130450193287748882093519743253970906445737076323388631551259281525673761521464457070183282952367912762917938927798821681921072535642129242854666788073051131299061206285360469938800671868633302918595546559331551212345164062815988396359214756491367524560074605770974503801668929162909301115859202829667843231469176278514190759538238555601653915471348888246124037515672651005456647578541420747605732786062856266482803248391343381148122839308684649277602497712294610414863984519223592500261985720483416681615211864640322536984576992511682625688123073477902974228512630222179491028406627640405863281915192929512020811691683132144089925734033030123841262008372844551817341801149212835713903822912110136502500812015039684523796118474236108889576145812790485096678443965414808946324753521693226067557412079606826394266987309245401126339874911016483561945621966582628807143755049537019714553875852866443198799753773321616737675676055286565550344547315145489568224588779467621723214846506583949626240395208356563931394951796329062516868271919725568260256370812566953298177381042095161765231647923971540244814088661166151738078639209206809946313166417344211826601807505646831079490788795430514910581020424621894643221506949651481550547972696596996681513875911293277243749138998558033144207402728866271634428623582796445967691694668880541928365702010145855496729101157269002201705975624778947857399081668692317614087918237971630291558354287239397456262918967566404162949964343716022778142456501811653634872441154951842835307431375451229809165809984922057260163071166616260203975351712468687077910818351246801689775052325287137297667038927440754586480188912493846508700801356054547675510752813453797272482074982821933437114101518196200493579760356543851906762564843908056605518816897910029353336779395993772483272626752787806746911602815273483755422110768451478998220372936439393163302970260988444739895429526138310936435365752400725554515447562730663222393622561585338963774402597287321537103279721069204595743115035894770492738893846175788531896434016102240644730992576338071478242736676787183512837467701021940543227830879181983196309308834672623313872062244499875939998453563464716046223725289150598271516350016399678472569230499762177920464488724347543236172714030936968117244659585707751246973112881073925244037927142057624723135025086676606540058195337301137114315011033455037798388259422675380299832362630343088015457301146379114901840660370609694227636630814648106638076924168072843527407823101279578001485707344392561806955949066640936737591737160475904437258240161485639102635896315248896597036923019409776054549443149376263189500819464230160996380911606833653899574282632126421372783023363548609585193418752
3、继续转换获取最高效的结果
……(待续)