从头开始实现BigInteger的乘法(并确保它是O(n ^ 2))

时间:2011-05-15 04:12:57

标签: java bytearray biginteger

作为家庭作业,我正在实施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 个答案:

答案 0 :(得分:2)

字节乘法的结果是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
               // ...
           }

答案 1 :(得分:1)

避免溢出的最好方法是不要让它首先发生。使用更高的宽度数进行所有计算以避免出现问题。

例如,假设我们有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

你可能很想要将两个权力的分裂转换为比特运算,但这并不是必需的。