刚才看了一下分治法,还是没看懂。用java来实现的更是少之又少,我是个初学者,希望哪位高手可以用简单的程序来实现大整数乘法:
是用数组去实现,在线等回复,谢谢
是用数组去实现,在线等回复,谢谢
解决方案 »
- linux下调用jdic使用firefox浏览器查看网页,但是总是显示空白
- jtextArea里怎么设置文本颜色
- 关于:JFC下applicationwindow的composite之间的转换问题。求助各位牛人,在线等。
- 请问如何读取并设置主线程的优先级
- 过年了,sourceforge却上不了,特来散分。大家说,中国XX是不是有病啊,这些东西都限制了!!
- non-static variable probability cannot be reference form a static context
- 哪位大哥教我如何建一个个人网站?
- [求助]如何克隆??
- protected的用法过来看看
- 请教
- 高分求Ireport打印PDF中文字字体粗体斜体问题。
- 面试了两次,都是考基础题,我没有把基础题复习好,我真是失败。明天我又到一家公家面试,求祝福.........
另你也可以自己定义一个需要的类型
// 9223372036854775807L是Java的Long.MAX_VALUE
System.out.println(multiply(9223372036854775807L, 9223372036854775807L));
}
/*
* 由于积可能超过long的最大值,故返回String,Java类库中有BigDecimal,为了使算法更单纯,就没有用
*/
public static String multiply(long m1, long m2) { // 使m1和m2位数相等,并同时等于2的幂
int maxLength = (int)(Math.ceil(Math.log10(Math.max(m1, m2)))); // 两数中大数的位数
int length = 1 << (int)(Math.ceil(Math.log(maxLength)/Math.log(2))); // 就近增大为2的整数次幂 // 相乘,见下面的multiply()方法和distributeToArray()方法
byte[] result = multiply(distributeToArray(m1, length), distributeToArray(m2, length));
// 按反序获取结果数组中的位,并忽略高位上补的0
StringBuffer resultString = new StringBuffer();
for (int i = result.length, appended = 0; i > 0; i--)
if (result[i-1] != 0 || appended == 1) { // 从第一个非0位开始获取
resultString.append(result[i-1]);
appended = 1;
} return resultString.toString();
}
/*
* m1和m2长度必须相等且同为2的整数次幂
*/
private static byte[] multiply(byte[] m1, byte[] m2) { int length = m1.length; // 如果是一位相乘则直接返回结果数组
if (length == 1)
return distributeToArray(m1[0]*m2[0], 2); // 结果数组,长度是因数的2倍
byte[] result = new byte[length << 1];
// 因数长度的一半
int halfLength = length >> 1;
// m1的左半部
byte[] m1Left = new byte[halfLength];
System.arraycopy(m1, 0, m1Left, 0, halfLength); // m1的右半部
byte[] m1Right = new byte[halfLength];
System.arraycopy(m1, halfLength, m1Right, 0, halfLength); // m2的左半部
byte[] m2Left = new byte[halfLength];
System.arraycopy(m2, 0, m2Left, 0, halfLength); // m2的右半部
byte[] m2Right = new byte[halfLength];
System.arraycopy(m2, halfLength, m2Right, 0, halfLength);
// 分治法两两交叉相乘
byte[] resultLL = multiply(m1Left, m2Left);
byte[] resultLR = multiply(m1Left, m2Right);
byte[] resultRL = multiply(m1Right, m2Left);
byte[] resultRR = multiply(m1Right, m2Right);
System.arraycopy(resultLL, 0, result, 0, length); // 组合乘积,要注意进位
// 下面这三个循环写的比较傻,有更好的写法
for (int i = 0; i < length; i++) {
int s = result[i+halfLength] + resultLR[i];
if (s < 10)
result[i+halfLength] = (byte)s;
else {
result[i+halfLength] = (byte)(s-10); // 大于10则往高位进1
result[i+halfLength+1] += 1;
}
}
for (int i = 0; i < length; i++) {
int s = result[i+halfLength] + resultRL[i];
if (s < 10)
result[i+halfLength] = (byte)s;
else {
result[i+halfLength] = (byte)(s-10); // 大于10则往高位进1
result[i+halfLength+1] += 1;
}
}
for (int i = 0; i < length; i++) {
int s = result[i+length] + resultRR[i];
if (s < 10)
result[i+length] = (byte)s;
else {
result[i+length] = (byte)(s-10); // 大于10则往高位进1
result[i+length+1] += 1;
}
}
return result;
}
/*
* 该方法用来将整数按10进制位放入指定长度的byte数组,整数的高位也是数组的高位,不够填0
*/
private static byte[] distributeToArray(long l, int length) {
byte[] result = new byte[length];
for (int i = 0; l > 0; i++, l /= 10)
result[i] = (byte)(l % 10);
return result;
}}
程序的输出结果是:85070591730234615847396907784232501249
非得用数组啊? 我建议你研究一下BigDecimal的源代码,也许有收获!
int maxLength = (int)(Math.ceil(Math.log10(Math.max(m1, m2)))); // 两数中大数的位数
int length = 1 << (int)(Math.ceil(Math.log(maxLength)/Math.log(2))); // 就近增大为2的整数
请问,maxLength为什么是“两数中大数的位数”呢?
如果max=100,
maxLength求得为2
但是maxlength明显为3嘛
int length = 1 < < (int)(Math.ceil(Math.log(maxLength)/Math.log(2))); // 就近增大为2的整数
这两行代码能给我解释一下吗?的确不懂~~~~~