Java 实现BigInteger';s从无到有地乘以(并确保它为O(n^2))

Java 实现BigInteger';s从无到有地乘以(并确保它为O(n^2)),java,bytearray,biginteger,Java,Bytearray,Biginteger,作为家庭作业,我正在实现Karatsuba的算法,并将其与小学风格的大整数O(n^2)乘法算法进行比较 我猜我唯一的选择就是把数字带到它们的字节数组表示中,然后从那里开始计算 我被困在这里了。。。当使用*运算符时,我不知道如何检测/纠正数字是否溢出字节乘法或添加进位。有什么想法吗 public static BigInteger simpleMultiply(BigInteger x, BigInteger y){ //BigInteger result = x.multipl

作为家庭作业,我正在实现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;
    }
公共静态BigInteger simpleMultiply(BigInteger x,BigInteger y){
//BigInteger结果=x乘以(y);
字节[]xByteArray=x.toByteArray();
字节[]yByteArray=y.toByteArray();
int resultSize=xByteArray.length*yByteArray.length;
字节[][]行和列=新字节[resultSize][resultSize];

对于(int i=0;i字节乘法的结果是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
               // ...
           }
for(inti=0;i8;
//在这里处理溢出
// ...
}

避免溢出的最佳方法是不要让溢出发生在第一位。所有计算都使用更大的宽度数字,以避免出现问题

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

你可以想当然地将二次幂的除法转换成位运算,但这并不是必须的。

什么是低阶/高阶字节?每个字节的低7位就是低阶字节?当你将两个单独的数字相乘(比如,9*9)时,你会得到一个两位数的结果(81)。在本例中,8是高阶数字,1是低阶数字。如果将两个单独的字节(例如0xFF*0xFF)相乘,则得到一个2字节的结果(0xFE01)。在本例中,0xFE是高阶字节,0x01是低阶字节。您能解释一下行和列[i][j]=(字节)吗(结果&0xFF);和int-overflow=result>>8;?我不熟悉字节算术/移位,我想了解逻辑。如果您不熟悉位算术,我建议您提供一个快速教程,例如。我不知道在将结果值分配给行和列后如何处理溢出,它应该存储以供下一次迭代使用吗?两个几个月前,我在这里写了一个,其中还包括一个乘法。它不使用字节,而是使用
int
值(范围为0…100000000),将其乘以
long
,以避免溢出。@保罗:谢谢,但我需要1000位的整数。这不能处理进位问题。只要用于计算的类型(在我的示例中,
int
)的宽度是用于存储数字的类型的两倍(在
字节的情况下,
).这就是在四年级时,你用一位数字存储数字,而用两位数字进行乘法的方法。