liangbch 发表于 2008-12-1 12:44:42

55楼代码虽然有bug,但依然有正确的思想,我用其思想,改进了程序,速度提高1倍多,在计算10^8以内的smith素数时,用时从23秒提高到11秒。

55楼代码中,“j *= p;" 这句话隐藏了一个较难发现的bug. 如果 j<=end 且j*p>end. 但执行了j*=p后,j仍然有可能小于end,

例如:
    j=3251*3251= 10569001;
    j*=p 后,本应该是34359822251, 但由于整数溢出,j的值变为83883.

liangbch 发表于 2008-12-1 12:49:35

下面的代码段 筛出 base 到end之间所有smith数

g_valueArray的初值为 base+i;
g_digSumArray [ i ]的初值为 0;i=0;
while (primeTab*primeTab<=end && i<primeCount)
{
        DWORD k,m,np;
        DWORD npx;
        DWORD npx_end;
        BYTE dsum;

        np=primeTab;
        dsum=getDigSum2(np);
       
        k= (base + np-1)/np;
        if (k<np)
                k=np;
        m= k*np;
        while (m <=end)
        {
                g_valueArray /= np;
                g_digSumArray += dsum;
                m+= np;
        }
       
        npx=np;
        npx_end=end/npx;
        while (npx<=npx_end)
        {
                npx *= np;
                m= (base + npx-1)/npx*npx;
                while (m <=end)
                {
                        g_valueArray /= np;
                        g_digSumArray += dsum;
                        m+= npx;
                }
        }
        i++;
}

liangbch 发表于 2008-12-1 12:54:18

为了便于阅读,将输出 base到end之间的smith数的代码一并贴出for (i=0;i<SIFT_BLOCK_LEN && i+base<=n;i++)
{
        DWORD x=i+base;
        WORD s1= getDigSum2(x);
        WORD s2= g_digSumArray;
        if (s1==0)
             continue;
                       
        if ( g_valueArray !=1 && g_valueArray != x)
                s2+=getDigSum2(g_valueArray);
        if (s1==s2)
        {
                if (fp!=NULL)
                {
                        numBuff=x;
                        if ( countInBuff*sizeof(DWORD)>=sizeof(numBuff) )
                        {
                                fwrite(numBuff,sizeof(DWORD),countInBuff,fp);
                                countInBuff=0;
                        }
                }
                count++;
        }
}

suan1024 发表于 2008-12-1 17:38:48

大哥厉害啊!学习了!
页: 1 2 3 4 5 6 [7]
查看完整版本: K-Smith numbers