从头开始实现 BigInteger 乘法(并确保其时间复杂度为 O(n^2))
作为家庭作业,我正在实现 Karatsuba 的算法,并将其与小学风格的大整数 O(n^2) 乘法算法进行基准测试。
我想我在这里唯一的选择是将数字带到它们的字节数组表示中,然后从那里开始工作。
好吧,我被困在这里......当使用 * 运算符时,我不知道如何检测/纠正数字是否溢出字节乘法或添加进位。有什么想法吗?
public static BigInteger simpleMultiply(BigInteger x, BigInteger y){
//BigInteger result = x.multiply(y);
byte [] xByteArray = x.toByteArray();
byte [] yByteArray = y.toByteArray();
int resultSize = xByteArray.length*yByteArray.length;
byte [][] rowsAndColumns = new byte[resultSize][resultSize];
for (int i =0; i<xByteArray.length;i++)
for (int j=0; j<yByteArray.length;j++){
rowsAndColumns[i][j] = (byte )(xByteArray[i] * yByteArray[j]);
// how would I detect/handle carry or overflow here?
}
return null;
}
As homework, I'm implementing Karatsuba's algorithm and benchmarking it against a primary-school-style O(n^2) multiplication algorithm on large integers.
I guessed my only choice here was to bring the numbers to their byte array representations and then work them from there.
Well, I'm stuck here... when using the * operator, I don't know how would I detect/correct if the number overflows a byte multiplication or adds a carry. Any ideas?
public static BigInteger simpleMultiply(BigInteger x, BigInteger y){
//BigInteger result = x.multiply(y);
byte [] xByteArray = x.toByteArray();
byte [] yByteArray = y.toByteArray();
int resultSize = xByteArray.length*yByteArray.length;
byte [][] rowsAndColumns = new byte[resultSize][resultSize];
for (int i =0; i<xByteArray.length;i++)
for (int j=0; j<yByteArray.length;j++){
rowsAndColumns[i][j] = (byte )(xByteArray[i] * yByteArray[j]);
// how would I detect/handle carry or overflow here?
}
return null;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
字节乘法的结果是 2 个字节。您必须使用低位字节作为结果,使用高位字节作为进位(溢出)。
我还建议您注意字节的符号。由于 Java 中的字节是有符号的,因此您必须仅使用它们的低 7 位,或者将它们转换为整数并在相乘之前更正符号。
你会想要一个像这样的循环:
The result of a byte multiplication is 2 bytes. You have to use the low order byte as the result and the high order byte as the carry (overflow).
I would also advise you to be careful of the sign of your bytes. Since bytes in Java are signed, you'll have to either use only the low 7 bits of them or convert them to ints and correct the sign before multiplying them.
You'll want a loop like:
避免溢出的最好方法就是从一开始就不要让它发生。使用更高宽度的数字进行所有计算以避免出现问题。
例如,假设我们有 256 基数,每个数字都存储为单个无符号字节。
您可能会想将二的幂除法转换为位运算,但这并不是真正必要的。
The best way to avoid overflow is not to have it happen in the first place. Make all your calculations with a higher width numbers to avoid problems.
For example, lets say we have base 256 numbers and each digit is stored as a single unsigned byte.
You could be fancy and convert the divisions by powers of two into bit operations, but it isn't really necessary.