[英]Implementing BigInteger's multiply…from scratch (and making sure it's 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;
}
字節乘法的結果是2個字節。 您必須使用低位字節作為結果,高位字節作為進位(溢出)。
我還建議你小心你的字節符號。 由於Java中的字節是有符號的,因此您必須僅使用它們的低7位或將它們轉換為整數並在乘以它們之前更正符號。
你會想要一個循環:
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
// ...
}
避免溢出的最好方法是不要讓它首先發生。 使用更高的寬度數進行所有計算以避免出現問題。
例如,假設我們有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
你可能很想要將兩個冪的除法轉換成位運算,但這並不是必需的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.