【问题标题】:C# Zero-One Multiple OverflowException using ULong使用 ULong 的 C# 零一多重溢出异常
【发布时间】:2016-01-27 03:42:03
【问题描述】:

我试图找到最小的零一数(一个仅由零和一组成的数字,即 11001),它是通过 STDIN 输入的数字的倍数,但是当我输入 99999 时程序崩溃,这是应该作为输入值工作的测试用例之一应该在 1 到 100000 之间,程序在 ulong.Parse(binary); 在 Getmultiple(ulong n) 中。

我应该做些什么改变才能让它工作?

class Program
{
    static void Main(string[] args)
    {
        while (true)
        {
            string s = Console.ReadLine();

            ulong l;
            ulong.TryParse(s, out l);

            Console.WriteLine(Getmultiple(l));
        }
    }

    private static ulong Getmultiple(ulong n)
    {

        for (ulong i = 1; ; i++)
        {
            String binary = Convert.ToString((long) i, 2);

            ulong no = ulong.Parse(binary);

            if (no % n == 0)
            {
                return no;
            }
        }

    }

}

错误消息:

“System.OverflowException”类型的未处理异常发生在 mscorlib.dll

附加信息:值太大或太大 对于 UInt64 来说很小。

【问题讨论】:

  • 可能会更容易走过去而不是这样做。 let isValid = !s.Any(c => c != '1' && c != '0').
  • 来自 STDIN 的输入,在这种情况下存储在 's' 中不是我需要验证的零一数(它的值可以从 1 到 100000),它的输出应该是零一数,我正在使用 Convert.ToString((long) i, 2);获取二进制数(以 2 为底)
  • 我猜在 2^64 下没有 99,999 的“零一”倍数,那就是 ulong 的最大值...
  • 你可能是正确的@pseudoDust,也许它高于 2^64,有什么方法可以输出这样的数字,我需要输出所有有效的零一数字,输入范围为 1到 100000?
  • @A.Bhuttoo 使用BigInteger。另外,请附上您收到的错误消息的文本。

标签: c# algorithm math


【解决方案1】:

您溢出了 unsigned long 变量,这意味着没有 99999 的倍数符合您的要求,也小于 2^64。如果您重构代码以使用 BigInteger 而不是 unsigned long,那么您将不会遇到溢出问题。不过,您的算法可能需要一些时间才能找到解决方案...

我也会进行此更改,以健全地检查您的输入:

BigInteger l;
if(BigInteger.TryParse(s, out l))
    Console.WriteLine(Getmultiple(l));
else
    Console.WriteLine("Not a valid integer");

【讨论】:

  • 谢谢!这就是解决方案!
【解决方案2】:

看起来您对ulong no 的数字太大了,您可以使用ulong.TryParse 来避免这种情况。

    private static ulong Getmultiple(ulong n)
    {

        for (ulong i = 1; ; i++)
        {
            String binary = Convert.ToString((long)i,2);

            ulong no = 0;

            if (ulong.TryParse(binary,out no))
            {

                if (no % n == 0)
                {
                    return no;
                }
            }
            else
            {
                return 0;
            }
        }

    }

我选择为无效结果返回 0。

【讨论】:

  • 这是避免出现异常的好方法,但正如@pseudoDust 提到的,在 2^64 下可能没有 99,999 的零一倍,我需要输出该值在这种情况下高于 2^64,输出零不是有效输出。
【解决方案3】:

使用 BigInteger 有效!!一些因 ulong 失败的测试用例现在是 工作,感谢深奥的屏幕名称!

    static void Main(string[] args)
    {
        while (true)
        {
            string s = Console.ReadLine();

            BigInteger l;
            if (BigInteger.TryParse(s, out l))
                Console.WriteLine(Getmultiple(l));
            else
                Console.WriteLine("Not a valid integer");
        }
    }

    private static BigInteger Getmultiple(BigInteger n)
    {

        for (BigInteger i = 1; ; i++)
        {
            String binary = Convert.ToString((long) i, 2);

            BigInteger no = BigInteger.Parse(binary);

            if (no % n == 0)
            {
                return no;
            }
        }

    }

【讨论】:

  • i 不需要是BigInteger,只有no 可以。事实上,一旦i 变得太大,您的Convert.ToString((long) i, 2); 就会失败。您应该将i 保留为longulong
猜你喜欢
  • 1970-01-01
  • 2020-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-22
  • 2011-10-07
  • 2011-03-17
相关资源
最近更新 更多