As homework, I'm implementing Karatsuba's algorithm and benchmarking it against a primary-school-style O(n^2) multiplication algorithm on large integers.
作为家庭作业,我正在实施Karatsuba的算法,并针对大整数的小学式O(n ^ 2)乘法算法进行基准测试。
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;
}
2 个解决方案
#1
2
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).
字节乘法的结果是2个字节。您必须使用低位字节作为结果,高位字节作为进位(溢出)。
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.
我还建议你小心你的字节符号。由于Java中的字节是有符号的,因此您必须使用它们的低7位或将它们转换为整数并在乘以它们之前纠正符号。
You'll want a loop like:
你会想要一个循环:
for (int i =0; i<xByteArray.length;i++)
for (int j=0; j<yByteArray.length;j++){
// convert bytes to ints
int xDigit = xByteArray[i], yDigit = yByteArray[j];
// convert signed to unsigned
if (xDigit < 0)
xDigit += 256;
if (yDigit < 0)
yDigit += 256;
// compute result of multiplication
int result = xDigit * yDigit;
// capture low order byte
rowsAndColumns[i][j] = (byte)(result & 0xFF);
// get overflow (high order byte)
int overflow = result >> 8;
// handle overflow here
// ...
}
#2
1
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.
例如,假设我们有256个基数,每个数字都存储为一个无符号字节。
d1 = (int) digits[i] //convert to a higher-width number
d2 = (int) digits[j]
product = d1*d2 //ints can handle up to around 2^32. Shouldn't overflow w/ 256*256
result = product % 256
carry = product / 256
You could be fancy and convert the divisions by powers of two into bit operations, but it isn't really necessary.
你可能很想要将两个权力的分裂转换为比特运算,但这并不是必需的。
#1
2
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).
字节乘法的结果是2个字节。您必须使用低位字节作为结果,高位字节作为进位(溢出)。
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.
我还建议你小心你的字节符号。由于Java中的字节是有符号的,因此您必须使用它们的低7位或将它们转换为整数并在乘以它们之前纠正符号。
You'll want a loop like:
你会想要一个循环:
for (int i =0; i<xByteArray.length;i++)
for (int j=0; j<yByteArray.length;j++){
// convert bytes to ints
int xDigit = xByteArray[i], yDigit = yByteArray[j];
// convert signed to unsigned
if (xDigit < 0)
xDigit += 256;
if (yDigit < 0)
yDigit += 256;
// compute result of multiplication
int result = xDigit * yDigit;
// capture low order byte
rowsAndColumns[i][j] = (byte)(result & 0xFF);
// get overflow (high order byte)
int overflow = result >> 8;
// handle overflow here
// ...
}
#2
1
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.
例如,假设我们有256个基数,每个数字都存储为一个无符号字节。
d1 = (int) digits[i] //convert to a higher-width number
d2 = (int) digits[j]
product = d1*d2 //ints can handle up to around 2^32. Shouldn't overflow w/ 256*256
result = product % 256
carry = product / 256
You could be fancy and convert the divisions by powers of two into bit operations, but it isn't really necessary.
你可能很想要将两个权力的分裂转换为比特运算,但这并不是必需的。