Java 实现大整数加法、乘法、阶乘运算

来源:互联网 发布:北邮图书馆软件 编辑:程序博客网 时间:2024/05/19 20:57

自己写的一个大数运算程序,算法神马的都是最原始的——模仿电路中的加法器和乘法器的运算过程——不过好歹是实现了。大神看到欢迎指点,若是像我这样的小菜鸟也欢迎留言讨论。


本程序写了一个BigInt的大整数类,可用用字符串直接初始化。重新了toString方法方便输出。实现了基础的一位数加、乘方法,继而实现大数的加、乘。当初为了方便自己观察过程,每个计算方法都输出了相应的信息,用doShowInfo(boolean isShow)来控制是否显示信息。

(好吧,我知道自己写得很烂,将就着看吧)


主方法:

//计算1^1+2^2+3^3+...+20^20;public class LargeNumber {/** * @param args */public static void main(String[] args) {BigInt.doShowInfo(false);BigInt result = new BigInt("0");BigInt i = new BigInt("1");final BigInt Bi_1 = new BigInt("1");final BigInt Bi_20 = new BigInt("20");while(!BigInt.equal(i, Bi_20)){result = BigInt.plus(result , BigInt.factorial(i, i) );i = BigInt.plus(i, Bi_1);}System.out.println("1^1+2^2+3^3+...+20^20 = "+result);}};

BigInt类

public class BigInt {public char[] number;private static boolean isShowInfo = false;BigInt(int len) {number = new char[len];}// 用数组储存大数,倒叙存放// 即,若要储存123456789这个数字// 1 2 3 4 5 6 7 8 9// 对应的数组下标为: 8 7 6 5 4 3 2 1 0BigInt(char[] _number) {int j = _number.length - 1;number = new char[_number.length];for (int i = 0; i < _number.length; ++i, --j) {number[i] = (char) (_number[j] - '0');}}BigInt(String str) {number = new char[str.length()];for (int i = 0; i < str.length(); ++i) {number[i] = (char) (str.charAt(str.length() - i - 1) - '0');}}BigInt(BigInt b) {number = b.number;}public static BigInt plus(BigInt bi1, BigInt bi2) {int largeLen, smallLen;BigInt bigOne;if (bi1.number.length < bi2.number.length) {smallLen = bi1.number.length;largeLen = bi2.number.length;bigOne = bi2;} else {smallLen = bi2.number.length;largeLen = bi1.number.length;bigOne = bi1;}int loop = smallLen;R r = new R((char) 0, (char) 0);BigInt temp_num = new BigInt(largeLen + 1);char c = (char) 0;int i = 0;for (; i < loop; ++i) {r = basic_plus(bi1.number[i], bi2.number[i], r.c);c = r.c;temp_num.number[i] = r.n;}for (; i < largeLen; ++i) {r = basic_plus('\0', bigOne.number[i], r.c);c = r.c;temp_num.number[i] = r.n;}temp_num.number[i] = r.c;temp_num.trim();return temp_num;}public static BigInt multiply(BigInt bi1, BigInt bi2) {BigInt result = new BigInt(bi1.number.length + bi2.number.length); // result用于储存结果BigInt temp = new BigInt(bi1.number.length + 1); // temp用于储存每位数相乘的结果R r = new R((char) 0, (char) 0); // 保存结果和进位信息int i = 0;int j = 0;for (i = 0; i < bi2.number.length; ++i) { // 抽出bi2.numbe[i],与bi1.number中每一位相乘for (j = 0; j < bi1.number.length; ++j) { // 抽出bi1.number[j],与bi2.number[i]相乘r = basic_multiply(bi1.number[j], bi2.number[i], r.c); // r中保存结果和进位信息temp.number[j] = r.n;// 将结果保存到temp中}temp.leftMove(i);// 位数对齐,执行左移操作temp.number[i + j] = r.c;// 将最后的进位保存到temp中r.c = 0;result = plus(result, temp);// 将temp累加到result中temp.number = new char[bi1.number.length + 1];// 最高位清零}result.trim();// 清楚有效数字前的0p("multiply()", bi1 + "*" + bi2 + "=" + result);return result;}public static BigInt factorial(BigInt m, BigInt n) {final String tag = "factorial()";BigInt result = new BigInt("1");BigInt time = new BigInt("0");int i = 0;while (!BigInt.equal(time, n)) {result = multiply(result, m);time = plus(time, new BigInt("1"));}p(tag,m+"^"+n+"="+result);return result;}// 辅助内部类,保存进位信息和计算结果static private class R {public char n;// 个位数public char c;// 进位R(char _n, char _c) {n = _n;c = _c;}}// n1为被加数,n2为加数private static R basic_plus(char n1, char n2) {char result = (char) (n1 + n2);return new R((char) (result / 10), (char) (result % 10));}// n1为被加数,n2为加数,c为前一次运算的进位private static R basic_plus(char n1, char n2, char _c) {char result = (char) (n1 + n2 + _c);return new R((char) (result % 10), (char) (result / 10));}// n1为被乘数,n2为乘数,_c为前一次运算的进位private static R basic_multiply(char n1, char n2, char _c) {char result = (char) (n1 * n2 + _c);return new R((char) (result % 10), (char) (result / 10));}@Overridepublic String toString() {String s = "";for (int i = number.length - 1; i >= 0; --i) {s = s + String.valueOf((int) number[i]);}return s;}// 左移操作,leftMove(i) 相当于 number*10^iprivate void leftMove(int i) {p("leftMove()", "从" + this);if (i > 0) {char[] temp = number;// 保存原数据number = new char[number.length + i];// 重新分配内存空间if (number == null)System.out.println("leftMove() 内存分配失败!");for (int t = temp.length - 1; t >= 0; --t) {// 左移操作number[t + i] = temp[t];}for (int t = 0; t < i; ++t) {// 最右端填0number[t] = 0;}}p("leftMove()", "左移" + i + "位,左移后结果为:" + this);}// 删除有效数字前的0;private void trim() {final String tag = "trim()";p(tag,"从:"+this);int place = 0; // 记录有效数字的下标for (place = number.length - 1; place >= 0; --place) {// 寻找第一个有效数字if (number[place] != 0)break;}char[] temp;if (place == -1) { // 没有有效数字,即数字为0temp = new char[1];temp[0] = (char) 0;} else {int zeroNum = (number.length - 1) - place;// 有效数字左边0的个数temp = new char[number.length - zeroNum];for (int i = 0; i < temp.length; ++i) {temp[i] = number[i];}}number = temp;p(tag,"到:"+this);}// 比较相等public static boolean equal(BigInt bi1, BigInt bi2) {final String Tag = "equal()";boolean flag = true;if (bi1.number.length != bi2.number.length){flag = false;}else{for (int i = 0; i < bi1.number.length; ++i) {if (bi1.number[i] != bi2.number[i])flag = false;}}p(Tag,"比较"+bi1+","+bi2+"  结果:"+flag);return flag;}public static void doShowInfo(boolean _isShowInfo){isShowInfo = _isShowInfo;}// 显示计算信息,isShowInfo==true 时显示private static void p(String tag, String info) {if (isShowInfo)System.out.println(tag + " : " + info);}}


原创粉丝点击