C# 带有Biginteger计算的控制台应用程序冻结 问题

C# 带有Biginteger计算的控制台应用程序冻结 问题,c#,visual-studio,console-application,primes,freeze,C#,Visual Studio,Console Application,Primes,Freeze,带有Biginteger计算的控制台应用程序冻结 细节 我正在用C#开发一个控制台应用程序,它测试非常大的数字(10到几十到几百的幂)是否为素数。由于默认整数类型最多只能处理10^19的数字(long,ulong),因此我使用的是bitineger类。但当我在VisualStudio中以调试模式运行应用程序时,应用程序会冻结 static void Main(string[] args) { int exp = 100; var bi = BigI

带有Biginteger计算的控制台应用程序冻结

细节 我正在用C#开发一个控制台应用程序,它测试非常大的数字(10到几十到几百的幂)是否为素数。由于默认整数类型最多只能处理10^19的数字(
long
ulong
),因此我使用的是
bitineger
类。但当我在VisualStudio中以调试模式运行应用程序时,应用程序会冻结

    static void Main(string[] args)
    {
        int exp = 100;
        var bi = BigInteger.Pow(10, exp);
        var sw = new Stopwatch();
        sw.Start();
        for (int i = 0; i < 1000; i++)
        {
            bi++;
            Console.WriteLine($"{i}th try : {bi} ({sw.Elapsed.ToString("mm\\:ss\\.ff")})");

            bool b = IsPrime(bi);
            if (b)
            {
                Console.WriteLine($"{bi} is a prime number");
            }

            //GC.Collect();
        }
        sw.Stop();

        Console.Read();
    }

    static private bool IsPrime(BigInteger n)
    {
        if (n <= 1)
            return false;
        else if (n <= 3)
            return true;
        else if (n % 2 == 0 || n % 3 == 0)
            return false;
        for (BigInteger i = 5; i * i <= n; i += 6)
        {
            if (n % i == 0 || n % (i + 2) == 0)
                return false;
        }

        return true;

    }
static void Main(字符串[]args)
{
int exp=100;
var bi=biginger.Pow(10,exp);
var sw=新秒表();
sw.Start();
对于(int i=0;i<1000;i++)
{
bi++;
WriteLine($“{i}第次尝试:{bi}({sw.appeased.ToString(“mm\\\:ss\\.ff”)})”);
bool b=IsPrime(bi);
如果(b)
{
WriteLine($“{bi}是一个素数”);
}
//GC.Collect();
}
sw.Stop();
Console.Read();
}
静态私有bool IsPrime(大整数n)
{

如果(n你的算法基本上说:

你能被2整除吗?3呢?5?7?11?13?17?19呢

等等

对于较小的输入值,检查所有这些排列是快速的。对于较大的输入值,如果较大的输入值具有较小的因子(例如2、3、5或37),则检查可能是快速的

但是,如果大输入缺少一个小因子(或者因为它是素数,或者因为它的最小因子相当大),那么您的算法必须进行大量的检查。基本上,它必须检查三分之一(即六分之二)的数,直到输入的平方根为止(直到找到匹配为止).对于大数字,这涉及大量计算

如果花费的时间太长,您需要编写一个更好/更快的
IsPrime
算法。在这方面可能会有所帮助

您还可以考虑存储一些<强>大<强>素数的列表,以便能够快速查找这些数字(例如从数据库)而不是“计算”。

关于:

(但是控制台窗口仅每17秒刷新一次)


这是因为一些输入确实是基本的,因此需要17秒左右的时间来验证(即检查每个排列)。在您看来,控制台好像只每隔17秒刷新一次,但它却在计算17秒。然后,后续的计算非常快(因为它们不是素数)-所以看起来它们是“成批”出来的。

mjwills,程序在
IsPrime()
中的for循环中循环。这是通过放置断点来检查的。最小因子
10000000000000000000000000000000000000000000000‌​00000000000000000000‌​00000000000000000003‌​6
显然是
2
。因此
IsPrime()
应该在
上返回
false
,否则如果(n%2==0 | | n%3==0)
并且应该打印一行。我不确定
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000‌​00000000000000000000‌​00000000000000000037
。我运行了大约20分钟的程序,控制台没有显示任何新行。而且,程序正常运行直到
I
=35,然后突然停在
I
=36。bi
中的变化非常小。可能是重复的哦,我知道了!所以你说的是t行n在17秒后弹出,n+1在17.001s中弹出,n+2在17.002s中弹出,n+3在17.003s中弹出(列表还在继续)因此,看起来所有的行都是在17秒内完成的,这是不正确的。非常感谢!众所周知,分解是一个很难快速解决的问题;这就是为什么它是密码系统的基础。你可以做得比现在好得多,但一般来说不会做得太好。>你还可以考虑存储已知大素数的列表,以使这些数字能够快速查找(例如从数据库)而不是“计算”。“这是不实际的。从1到n的素数的粗略估计是n/log(n)。。对于N=10^100,它是10^97。整个数据的大小将至少是10^97字节。我怀疑是否有一个服务器可以存储这么多的数据。但是我可以使用一个高达10000的素数列表,以便在
for
循环中仅为
I
使用素数。
这是不实际的。
存储所有这些数据是不切实际的,是的。但是您可以存储其中的一个子集(例如,一些大的-存储小的没有任何意义,因为它们计算起来很快)。说到底,这是一种优化技术——你需要决定是用CPU来解决问题,还是用存储来解决问题,或者两者兼而有之。@Dixho:你怀疑有没有一台服务器可以存储这么多数据?这比宇宙中的原子数多出10多亿倍。现在是消除对t的所有怀疑的好时机他很重要。哈哈,谢谢@EricLippert(公平地说,你的评论对所有素数都是正确的,我不是100%确定它对所有已知的素数都是正确的)。@EricLippert完全同意你的观点。我怀疑使用所有可能的粒子,包括宇宙中的光子就足够了:)