C# 用数组表示的大数的乘法?

C# 用数组表示的大数的乘法?,c#,arrays,methods,C#,Arrays,Methods,数字以相反的顺序存储在数组中。下面是一个函数,它应该将两个数字相乘,lhs和rhs,并将乘积存储在result中: public static void MultiplyDigitArrays(int[] lhs, int[] rhs, int[] result) { int length1 = Math.Max(lhs.Length, rhs.Length); for (int i = 0; i < length1; i++) {

数字以相反的顺序存储在数组中。下面是一个函数,它应该将两个数字相乘,
lhs
rhs
,并将乘积存储在
result
中:

public static void MultiplyDigitArrays(int[] lhs, int[] rhs, int[] result)
{        
     int length1 = Math.Max(lhs.Length, rhs.Length);
     for (int i = 0; i < length1; i++)
     {
        int[] PartialProduct = new int[result.Length];

        int length2 = Math.Min(lhs.Length, rhs.Length);
        for (int j = 0; j < length2; j++)
        {
            int multiplicand = (lhs.Length < rhs.Length) ? rhs[i] : lhs[i];
            int multiplier = (lhs.Length < rhs.Length) ? lhs[j] : rhs[j];

            int product = PartialProduct[i + j] + multiplicand * multiplier;

            PartialProduct[i + j] = product % 10;
            int carry = product / 10;

            PartialProduct[i + j + 1] = PartialProduct[i + j + 1] + carry;
        }
        SumDigitArrays(PartialProduct, result, result);
    }
}
结果是:

00132
而不是预期的:

00121
我做错了什么?
对于MCVE:

public static void PrintArray(int[] Array)
{
    int length = Array.Length;
    for (int i = length - 1; i >= 0; i--)
    {
        Console.Write(Array[i]);

    }
}

public static void SumDigitArrays(int[] a, int[] b, int[] result)
{
    int length = Math.Max(a.Length, b.Length);
    for (int i = 0; i < length; i++)
    {
        int lhs = (i < a.Length) ? a[i] : 0;
        int rhs = (i < b.Length) ? b[i] : 0;

        int sum = result[i] + lhs + rhs;
        result[i] = sum % 10;

        int carry = sum / 10; 

        if (i + 1 < result.Length)
        {
            result[i + 1] = result[i + 1] + carry;
        }
    }
}
publicstaticvoidprintary(int[]数组)
{
int length=Array.length;
对于(int i=length-1;i>=0;i--)
{
Console.Write(数组[i]);
}
}
公共静态无效SumDigitarray(int[]a,int[]b,int[]result)
{
int length=Math.Max(a.length,b.length);
for(int i=0;i
我不完全理解您执行的逻辑,但是

 int product = PartialProduct[i + j] + multiplicand * multiplier;
被评估为

int product = PartialProduct[i + j] + (multiplicand * multiplier);
你打算这样做吗

int product = (PartialProduct[i + j] + multiplicand) * multiplier;

这可以解释您的错误。

原因是调用
SumDigitArrays
时使用的第三个参数应该为空。相反,您向它提供结果变量,该变量包含除第一次迭代之外的任何迭代的数据

按照以下方式实施您的方法:

    public static int[]  MultiplyDigitArrays(int[] lhs, int[] rhs)
    {
        int length1 = Math.Max(lhs.Length, rhs.Length);
        var result = new int[length1* length1];

        for (int i = 0; i < length1; i++)
        {
            int[] PartialProduct = new int[length1 * length1];

            int length2 = Math.Min(lhs.Length, rhs.Length);
            for (int j = 0; j < length2; j++)
            {
                int multiplicand = (lhs.Length < rhs.Length) ? rhs[i] : lhs[i];
                int multiplier = (lhs.Length < rhs.Length) ? lhs[j] : rhs[j];

                int product = PartialProduct[i + j] + multiplicand * multiplier;

                PartialProduct[i + j] = product % 10;
                int carry = product / 10;

                PartialProduct[i + j + 1] = PartialProduct[i + j + 1] + carry;
            }
            result = SumDigitArrays(PartialProduct, result);
        }

        return result;
    }


    public static int[] SumDigitArrays(int[] a, int[] b)
    {
        int length = Math.Max(a.Length, b.Length);
        var result = new int[length];

        for (int i = 0; i < length; i++)
        {
            int lhs = (i < a.Length) ? a[i] : 0;
            int rhs = (i < b.Length) ? b[i] : 0;

            int sum = result[i] + lhs + rhs;
            result[i] = sum % 10;

            int carry = sum / 10;

            if (i + 1 < result.Length)
            {
                result[i + 1] = result[i + 1] + carry;
            }
        }

        return result;
    }
公共静态int[]多数字射线(int[]lhs,int[]rhs)
{
int length1=数学最大值(左侧长度,右侧长度);
var结果=新整数[length1*length1];
对于(int i=0;i
除了给出的另外两个答案(这两个答案正好解决了您的问题),除非您有非常特殊的需要,否则如果您需要将非常大的数字相乘,我建议您选择

根据您的具体需要(如果您的数字必须以整数数组形式来来去去,这是存储任何数字的一种奇怪方式),您的
乘法可以变成:

public static void MultiplyDigitArrays(int[] lhs, int[] rhs, int[] result)
{        
    var n1 = BigInteger.Parse(string.Join("", lhs));
    var n2 = BigInteger.Parse(string.Join("", rhs));
    var resultBi = BigInteger.Multiply(n1, n2);     
    Array.Clear(result, 0, result.Length);
    var stResult = resultBi.ToString().PadLeft(result.Length, '0');
    for(int i = 0; i < stResult.Length; i++)
    {
        result[(stResult.Length-1)-i] = int.Parse(stResult[i].ToString());
    }
}
public static string MultiplyBigNumbers(string lhs, string rhs)
{        
    var n1 = BigInteger.Parse(lhs);
    var n2 = BigInteger.Parse(rhs);
    return BigInteger.Multiply(n1, n2).ToString();      
}
只要叫它:
MultiplyBigNumbers(“3242”、“42349”)

再次,我建议您一直使用
biginger
,并在需要存储时对其进行转换(对于这一点,
byte
数组更有意义,您可以使用
ToByteArray()
获取它)或显示(这可以通过
ToString()
调用轻松完成)


请注意,为结果传递数组也很奇怪(无论如何对于.NET来说),因为您不需要原始值。您最好返回一个数组并在函数本身中计算所需的长度,而不要让调用方计算出来。

您是否在调试器中一步一步地运行它以查看问题所在?@DStanley是的,F10/11已被推送了很多次,并且在原始代码中有很多
WriteLines()
使用局部变量的当前值。一段时间后,你需要另一双眼睛……你在SumDigitArrays(inti=0;i超出范围的异常
除了@WicherVisser的答案之外,您可能还想看看,除非您对这种实现有非常具体的需求。我写的答案基本相同+1@eh编辑前我投了赞成票(只是解释一下)。我不确定实现,还没有测试,但是传递一个空数组对我有效(我在测试的地方,我的实现不同,只是测试)@eh让我知道什么对你不起作用。(编辑涉及的是文本中的一个输入错误,而不是代码片段。@Jcl是的,它现在工作正常;我以前看到的任何东西都没有……应该注意,OP也必须更改其
Main
。是的,我只是在尝试不同的值时注意到了错误,will+1@ScottChamberlain的回答如下,这也是正确的:-)很好+顺便说一句,可能是操作人员从C/Matlab移植了他的代码。解释了这种奇怪的技术。@WicherVisser赞赏地说,我从未使用过Matlab,但如果它将大整数存储为0-9个整数的数组,每个整数代表一个以10为基数的数字,我会说他们做错了(我怀疑他们做错了,因为它很有名,但我见过更糟的:-)
public static string MultiplyBigNumbers(string lhs, string rhs)
{        
    var n1 = BigInteger.Parse(lhs);
    var n2 = BigInteger.Parse(rhs);
    return BigInteger.Multiply(n1, n2).ToString();      
}