C#素数发生器,最大输出位阵列

C#素数发生器,最大输出位阵列,c#,primes,bitarray,C#,Primes,Bitarray,(C#,主发电机) 下面是我和一个朋友在翻查的一些代码: public List<int> GetListToTop(int top) { top++; List<int> result = new List<int>(); BitArray primes = new BitArray(top / 2); int root = (int)Math.Sqrt(top); for (int i = 3

(C#,主发电机) 下面是我和一个朋友在翻查的一些代码:

public List<int> GetListToTop(int top)
{            
    top++;
    List<int> result = new List<int>();
    BitArray primes = new BitArray(top / 2);
    int root = (int)Math.Sqrt(top);
    for (int i = 3, count = 3; i <= root; i += 2, count++)
    {
        int n = i - count;
        if (!primes[n])
            for (int j = n + i; j < top / 2; j += i)
            {
                primes[j] = true;
            }
    }
    if (top >= 2)
        result.Add(2);            
    for (int i = 0, count = 3; i < primes.Length; i++, count++)
    {
        if (!primes[i])
        {
            int n = i + count;
            result.Add(n);
        }
    }

    return result;
}
public List getlisttop(int-top)
{            
top++;
列表结果=新列表();
BitArray primes=新的BitArray(top/2);
int root=(int)Math.Sqrt(top);
for(int i=3,count=3;i=2)
结果:增加(2);
对于(int i=0,count=3;i
在我的傻瓜AMD x64 1800+(双核)上,适用于34546.875ms中10亿以下的所有素数。问题似乎是位数组中存储了更多。试图盘车超过20亿次超出了bitarray想要存储的容量。有什么办法吗?

我会将阵列的部分“交换”到磁盘上。我的意思是,将您的位数组划分为5亿个位块,并将它们存储在磁盘上

在同一时间内存中只有几个块。使用C#(或任何其他OO语言),应该可以很容易地将庞大的数组封装在这个分块类中


您可以用较慢的生成时间来支付,但在我们获得更大的地址空间和128位编译器之前,我看不到任何解决方法。

或者作为Pax建议的替代方法,使用.NET 4.0中新的内存映射文件类,让操作系统决定在任何给定时间哪些块需要在内存中


但是请注意,您需要尝试并优化算法以增加局部性,这样您就不会不必要地在内存中交换页面(听起来比这句话更复杂)。

使用多个位数组来增加最大大小。如果一个数字要进行大的位移位,则将其结果存储在一个位数组中,用于存储位33-64

BitArray second = new BitArray(int.MaxValue);
long num = 23958923589;
if (num > int.MaxValue)
{
    int shifted = (int)num >> 32;
    second[shifted] = true;
}

long request = 0902305023;
if (request > int.MaxValue)
{
    int shifted = (int)request >> 32;
    return second[shifted];
}
else return first[request];
当然,如果BitArray支持System.Numerics.BigInteger的大小,那就太好了。
切换到磁盘会使代码速度非常慢。
我有一个64位操作系统,我的位数组也被限制为32位

PS:你的素数计算看起来很复杂,我的是这样的:

for (int i = 2; i <= number; i++)
    if (primes[i])
        for (int scalar = i + i; scalar <= number; scalar += i)
        {
            primes[scalar] = false;
            yield return scalar;
        }

for(int i=2;i筛选算法的性能会更好。我可以在不到4分钟的时间内确定int范围内的所有32位素数(总计约1.05亿)。当然,返回素数列表是另一回事,因为内存需求将略高于400 MB(1 int=4字节)。使用for循环,数字被打印到一个文件中,然后导入到数据库中以获得更多乐趣:)但是对于64位素数,该程序需要多次修改,可能需要在多个节点上分布式执行。另请参考以下链接


我们现在有64位编译器,不是吗?我知道我们在大型机领域是这样做的。我想英特尔C++编译器(至少)是64位,因为他们已经有一段时间没有这些芯片了。