基础算法,大数加法和乘法的实现
来源:互联网 发布:淘宝营销思路 编辑:程序博客网 时间:2024/04/28 01:32
计算机中的基本数据类型都是定长的,比如long 64位 int32位。如果只使用基本的数据类型,那就只能实现操作数和结果都在 这个长度之内加法或乘法。虽然 int可以达到20亿数量级,可是如果数字更大呢?如果数字大到连long 都装不下呢?
表示数据应该不成问题,一个int 表示不了,那么可以用多个int 也就是 int[] 来表示,数组的长度取决于数字大小。
下面来决绝运算问题,先从最简单的搞起。。加法
算法直接给出
private static int[] add(int[] x, int[] y) {
// If x is shorter, swap the two arrays
if (x.length < y.length) {
int[] tmp = x;
x = y;
y = tmp;
}
int xIndex = x.length;
int yIndex = y.length;
int result[] = new int[xIndex];
long sum = 0;
// Add common parts of both numbers
while(yIndex > 0) {
sum = (x[--xIndex] & LONG_MASK) +
(y[--yIndex] & LONG_MASK) + (sum >>> 32);
result[xIndex] = (int)sum;
}
// Copy remainder of longer number while carry propagation is required
boolean carry = (sum >>> 32 != 0);
while (xIndex > 0 && carry)
carry = ((result[--xIndex] = x[xIndex] + 1) == 0);
// Copy remainder of longer number
while (xIndex > 0)
result[--xIndex] = x[xIndex];
// Grow result if necessary
if (carry) {
int bigger[] = new int[result.length + 1];
System.arraycopy(result, 0, bigger, 1, result.length);
bigger[0] = 0x01;
return bigger;
}
return result;
}
可以这么理解,类比10进制加法,10进制加法的规则是 相同的位数相加
比如 10进制数,我们定义 10 进制数组 位 int10[]
int10[] a,int10[] b int10[c]
c=a+b
回忆小学知识,列出下列等式
c[i]=a[i]+b[i]+d[i-1]
其中d[i-1]是a[k-1]+b[i-1] 的进位
那么,我们可以类比来看了,既然 10进制数组可以这样运算,为什么 11进制不可以呢?为什么20进制不可以呢,为什么2^32 进制不可以呢?
当然可以。
我们把数组中的一个整数看成一个位,于是一切都清晰了,关键就在这几行代码。
while(yIndex > 0) {
sum = (x[--xIndex] & LONG_MASK) +
(y[--yIndex] & LONG_MASK) + (sum >>> 32);
result[xIndex] = (int)sum;
}
其中 (sum >>> 32) 是计算这次加法的溢出部分,溢出部分就是要进位的部分,在加法中进位或者是1 或者是0.
这样,计算时间复杂度和空间复杂度都是 O(n)。
我们将问题延伸一下,来计算下乘法
private int[] multiplyToLen(int[] x, int xlen, int[] y, int ylen, int[] z) {
int xstart = xlen - 1;
int ystart = ylen - 1;
if (z == null || z.length < (xlen+ ylen))
z = new int[xlen+ylen];
long carry = 0;
for (int j=ystart, k=ystart+1+xstart; j>=0; j--, k--) {
long product = (y[j] & LONG_MASK) *
(x[xstart] & LONG_MASK) + carry;
z[k] = (int)product;
carry = product >>> 32;
}
z[xstart] = (int)carry;
//关键代码在这里
for (int i = xstart-1; i >= 0; i--) {
carry = 0;
for (int j=ystart, k=ystart+1+i; j>=0; j--, k--) {
long product = (y[j] & LONG_MASK) *
(x[i] & LONG_MASK) +
(z[k] & LONG_MASK) + carry;
z[k] = (int)product;
carry = product >>> 32;
}
z[i] = (int)carry;
}
////////////////////////////////////
return z;
}
上面标注关键代码部分 其实就是乘法法则描述的,把每一个整数看成一位来处理
- 基础算法,大数加法和乘法的实现
- 大数加法和大数乘法的实现
- 大数乘法、大数加法实现
- 大数加法和乘法
- 大数加法和乘法
- 大数加法和大数乘法
- 大数加法和大数乘法
- 大数的加法,乘法,全排列实现
- 大数的加法和乘法,高精度
- 99的99次方----大数乘法和大数加法
- 大数加法、减法和乘法
- 大数运算之加法和乘法算法C++模板
- 大数乘法与大数加法 java实现
- 大数的加法与乘法
- 大数的加法,减法,乘法
- 大数加法和大数乘法模板函数
- Java 大数类 目前仅实现正数的加法和乘法
- 大数加法 大数乘法
- 创建简单按钮2
- OpenWrt系列教程汇总
- WR703N OpenWrt 配置流程
- farmerbuff(C语言实现小球)
- 定义__asm块作为C宏
- 基础算法,大数加法和乘法的实现
- CLisp 17:恢复错误的再启动特性restart
- 水果机(java实现)java多态性
- C++运算符优先级
- OSGi Bundle之Hello World
- 双端队列部分操作(剩下部分待补)
- 微信架构的启示
- Redis常用数据类型
- Oracle group by 用法实例详解