用数组进行大数运算

来源:互联网 发布:剑三红唇御姐捏脸数据 编辑:程序博客网 时间:2024/05/02 01:50

有时在程序中会使用到大数运算,也就是两个非常大的数进行加减乘除运算,而我们的计算机一般只能去处64位的数字,超过这个数字就会发生溢出。

基于数组的大数运算完全按照手工计算的方法来进行:


如:

29+55=84

 

个位5 + 9等于14,即4然后进1,然后十位是1 + 2 + 5为8

然后在计算中我们可以换一种思路,改成统一进位,即:

个位:5 + 9 = 14

十位:2 + 5 = 7

然后统一由个位到十位进行进位,十位进位=个位/10,个位留位=个位%10

以上程序用程序来写就变成:

int a[2] = {2, 9}

int b[2] = {5, 5}

int result[2] = {0, 0}

result[0] = a[0] + b[0]

result[1] = a[1] + b[1]

// 这时result[2] = {7, 14}

result[0] = result[0] + result[1] / 10;

result[1] = result[1] % 10

// 这时result[2] = {8, 4}

当然以上只是示例程序,在实际运行中使用循环来完成计算。

 

下面是一种Java程序的实现应用:

public static void main(String[] args) {

BigNumber a = new BigNumber("12345678901234567890");

BigNumber b = new BigNumber("98765432109876543210");

 

System.out.println(a.multiply(b).toString());

}

 

BigNumber类的具体代码如下:

package cn.hatterjiang.math;

 

public class BigNumber implements Comparable<BigNumber>, Serializable {

 

private static final long serialVersionUID = 7089673841394145916L;

 

public static final BigNumber ZERO = new BigNumber();

 

public static final BigNumber ONE = new BigNumber("1");

 

private static final int DIVIDE_GROUP_SIZE = 4;

 

private int numLength = 10000;

 

private int[] number = new int[numLength];

 

public BigNumber() {

}

 

public BigNumber(String num) {

number = BigNumber.valueOf(num).number;

}

 

public BigNumber multiply(BigNumber num) {

BigNumber mul = new BigNumber();

for (int i = 0; i < num.numLength; i++) {

int n = num.number[num.numLength - 1 - i];

if (n != 0) {

BigNumber temp = (BigNumber) clone();

temp.multiply10(i);

temp.multiply0(num.number[num.numLength - 1 - i]);

mul.add0(temp);

}

}

return mul;

}

 

public BigNumber add(BigNumber num) {

BigNumber sum = (BigNumber) clone();

sum.add0(num);

return sum;

}

 

public void clear() {

int groups = numLength / DIVIDE_GROUP_SIZE;

for (int i = 0; i < groups; i++) {

int j = i * DIVIDE_GROUP_SIZE;

number[j] = 0;

number[j + 1] = 0;

number[j + 2] = 0;

number[j + 3] = 0;

}

if ((groups * DIVIDE_GROUP_SIZE) < numLength) {

int left = numLength - (groups * DIVIDE_GROUP_SIZE);

for (int i = 0; i < left; i++) {

number[numLength - 1 - i] = 0;

}

}

}

 

public static BigNumber valueOf(int value) {

return BigNumber.valueOf(String.valueOf(value));

}

 

public static BigNumber valueOf(long value) {

return BigNumber.valueOf(String.valueOf(value));

}

 

public static BigNumber valueOf(String value) {

BigNumber num = new BigNumber();

if ((value != null) && (value.length() > 0)) {

if (value.length() > num.numLength) {

throw new RuntimeException("value length exceed.");

}

int offset = num.numLength - value.length();

for (int i = 0; i < value.length(); i++) {

num.number[offset + i] = Integer.parseInt(value.substring(i,

(i + 1)));

}

}

return num;

}

 

@Override

public String toString() {

StringBuilder sb = new StringBuilder();

int i;

for (i = 0; i < numLength; i++) {

if (number[i] != 0) {

break;

}

}

for (; i < numLength; i++) {

sb.append(String.valueOf(number[i]));

}

if (sb.length() < 1) {

sb.append("0");

}

return sb.toString();

}

 

@Override

public Object clone() {

BigNumber mul = new BigNumber();

System.arraycopy(number, 0, mul.number, 0, numLength);

return mul;

}

 

@Override

public boolean equals(Object num) {

if (num instanceof BigNumber) {

return (compareTo((BigNumber) num) == 0);

} else {

return false;

}

}

 

public int compareTo(BigNumber num) {

for (int i = 0; i < numLength; i++) {

if (number[i] != num.number[i]) {

return (number[i] - num.number[i]);

}

}

return 0;

}

 

public void add0(BigNumber num) {

for (int i = 0; i < numLength; i++) {

number[i] = number[i] + num.number[i];

}

refresh();

}

 

private void multiply0(int no) {

for (int i = 0; i < numLength; i++) {

number[i] *= no;

}

refresh();

}

 

private void multiply10(int no) {

for (int i = 0; i < no; i++) {

if (number[i] != 0) {

throw new RuntimeException("over flow");

}

}

for (int i = 0; i < (numLength - no); i++) {

number[i] = number[i + no];

}

for (int i = 0; i < no; i++) {

number[numLength - 1 - i] = 0;

}

}

 

private void refresh() {

for (int i = (numLength - 1); i > 0; i--) {

int no = number[i];

if (no > 9) {

number[i - 1] += no / 10;

number[i] = no % 10;

}

}

if (number[0] > 9) {

throw new RuntimeException("over flow");

}

}

}

 

程序存在的问题是没有使用动态数组,而是使用一个静态数组来计算数据,所以存在一定的问题,如不能计算过大的数字等。还存在的问题是无法计算减法和除法,如果确实需要这些功能的话可以使用Java中提供的BigInteger类。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/jht5945/archive/2008/05/29/2494396.aspx

原创粉丝点击