如何使用递归函数(C#,D&C)避免非常大的数字的溢出乘法

Posted

技术标签:

【中文标题】如何使用递归函数(C#,D&C)避免非常大的数字的溢出乘法【英文标题】:How to avoid overflow multiplication of very big numbers with recursive function (C# , D&C) 【发布时间】:2015-06-13 13:20:08 【问题描述】:

当递归函数触发并返回结果时,它会因为数据溢出而崩溃。如何使用这个 D&C 算法来避免这个问题?

static long long zarb(long a, long b, int n)

        Int64 w, x, y, z;
        int s;

        if (a == 0 || b == 0) 
           return 0;

        if (n <25)
            return a * b;
        else
        
            s = n / 2;
            long p = power(2, s);
            w = a / p;
            x = a % p;
            y = b / p;
            z = b % p;
            return (zarb(w, y, n / 2) * power(2, 2 * s) + p * (zarb(w, z, n / 2) + zarb(x, y, n / 2)) + zarb(x, y, n / 2));
        


static long power(int x, int y)

        long sum = 1;

        if (y == 0) 
           return 0;

        for (int i = 1; i <= y; i++)
            sum = sum * x;

        return sum;

【问题讨论】:

长数据类型溢出?你得到什么异常?是OverflowException 还是***Exception 那么你到底想要什么样的行为呢?防止它崩溃很容易,但你希望它如何处理? static long long 这是 C#,不是 C。这里没有 long long。最好不要混用Int64long。它们是相同的东西,但它给读者一种不好的感觉。 @xanatos 也许是因为在他的情况下长时间溢出,OP 尝试将其写入两次以使其变得很长:p power 在技术上是错误的。 x^0 == 1,而不是 0 【参考方案1】:

您的代码没有真正的问题,它适用于一定范围的输入。如果您需要能够输入将导致值超出 int64 范围的值,请尝试其他类型。 System.Numerics 内置于 .NET 中,并且有一个 BigInteger 类型,该类型声称“任意大整数,其值在理论上没有上限或下限”。运行这些大值输入可能需要一段时间,但应该没问题。

https://msdn.microsoft.com/en-us/library/system.numerics.biginteger%28v=vs.110%29.aspx

【讨论】:

以上是关于如何使用递归函数(C#,D&C)避免非常大的数字的溢出乘法的主要内容,如果未能解决你的问题,请参考以下文章

c#如何让递归函数输出多个结果

递归函数如何返回一些东西?

使用 D&C/递归的最大子数组

C 递归

VBA如何在使用许多整数时避免递归

PHP 小技巧之如何避免参数多次传递?