- 注册时间
- 2008-2-6
- 最后登录
- 1970-1-1
- 威望
- 星
- 金币
- 枚
- 贡献
- 分
- 经验
- 点
- 鲜花
- 朵
- 魅力
- 点
- 上传
- 次
- 下载
- 次
- 积分
- 51573
- 在线时间
- 小时
|
楼主 |
发表于 2008-7-17 16:37:01
|
显示全部楼层
带状态保存的搜索大四生素数程序
最大到(2^31-1) * 9999# + 10^8- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
- #include <assert.h>
- #include <sys/time.h>
- #include "gmp.h"
-
- unsigned long primes[1280]; //小于10000素数,实际上有1229个
- unsigned long quadprimes[4800]; //小于10^8四生素数,实际上有4768组
- unsigned long sieve[30030];
- unsigned long template[30030];
- unsigned long A, B, C;
-
- void
- InitPrimes (void)
- {
- primes[0] = 2;
- primes[1] = 3;
- primes[2] = 5;
- primes[3] = 7;
- primes[4] = 11;
- primes[5] = 13;
- primes[6] = 17;
- primes[7] = 19;
- primes[8] = 23;
- primes[9] = 29;
- primes[10] = 31;
- primes[11] = 37;
- primes[12] = 41;
- primes[13] = 43;
- primes[14] = 47;
- primes[15] = 53;
- primes[16] = 59;
- primes[17] = 61;
- primes[18] = 67;
- primes[19] = 71;
- primes[20] = 73;
- primes[21] = 79;
- primes[22] = 83;
- primes[23] = 89;
- primes[24] = 97;
- }
-
- void
- InitSieve (void)
- {
- unsigned long i;
- for (i = 1; i <= 9999; i += 2)
- sieve[i] = 1;
- }
-
- void
- Sieve (void)
- {
- unsigned long i, j, start;
- for (i = 0; i <= 24; i++)
- {
- start = primes[i] * primes[i];
- for (j = start; j <= 9999; j += 2 * primes[i])
- sieve[j] = 0;
- }
- }
-
- void
- StoreSieveResult (void)
- {
- unsigned long i, k;
- k = 25;
- for (i = 101; i <= 9999; i += 2)
- if (sieve[i])
- primes[k++] = i;
- for (; k < 1280; k++)
- primes[k] = 0;
- primes[1229] = 10007; //以这个素数结束,否则下面的四生素数筛在接近10^8会超越1229素数的范围
- }
-
- void
- InitQuadPrimes (void)
- {
- unsigned long i, k = 0;
- for (i = 0; i < 1229; i++)
- if ((primes[i + 1] - primes[i] == 2) && (primes[i + 2] - primes[i] == 6)
- && (primes[i + 3] - primes[i] == 8))
- quadprimes[k++] = primes[i]; //共12组
- }
-
- void
- InitTemplate (void)
- {
- unsigned long i;
- for (i = 1; i < 30030; i += 2)
- template[i] = 1;
- for (i = 0; i < 30030; i += 2)
- template[i] = 0;
- for (i = 3; i < 30030; i += 6)
- template[i] = 0;
- for (i = 5; i < 30030; i += 10)
- template[i] = 0;
- for (i = 7; i < 30030; i += 14)
- template[i] = 0;
- for (i = 11; i < 30030; i += 22)
- template[i] = 0;
- for (i = 13; i < 30030; i += 26)
- template[i] = 0;
- }
-
- void
- SearchQuadSieve (void)
- {
- unsigned long start, end;
- unsigned long i, j, k, m, s_start;
-
- InitTemplate ();
-
- //首次筛过程
- start = 0;
- end = 30030;
- memcpy (sieve, template, 30030 * sizeof (unsigned long));
-
- for (j = 6; primes[j] * primes[j] <= end; j++)
- {
- s_start = primes[j] * primes[j];
- for (k = s_start; k < 30030; k += 2 * primes[j])
- sieve[k] = 0;
- }
-
- m = 12;
- for (i = 10001; i < 30030; i += 10)
- if ((sieve[i]) && (sieve[i + 2]) && (sieve[i + 6]) && (sieve[i + 8]))
- quadprimes[m++] = i;
-
- //完整筛过程,经测试剩余的数字是99999900-99999999,不存在四生素数
- for (i = 1; i < 100000000 / 30030; i++)
- {
- start = i * 30030;
- end = start + 30030;
- memcpy (sieve, template, 30030 * sizeof (unsigned long));
-
- for (j = 6; primes[j] * primes[j] <= start; j++)
- {
- s_start = (start / primes[j]) * primes[j] + primes[j];
- if (s_start % 2 == 0)
- s_start += primes[j];
- s_start -= start;
- for (k = s_start; k < 30030; k += 2 * primes[j])
- sieve[k] = 0;
- }
-
- for (; primes[j] * primes[j] < end; j++)
- {
- s_start = primes[j] * primes[j] - start;
- for (k = s_start; k < 30030; k += 2 * primes[j])
- sieve[k] = 0;
- }
-
- s_start = (start / 30) * 30 + 11;
- if (s_start < start)
- s_start += 30;
- s_start -= start;
-
- for (k = s_start; k < 30030; k += 30)
- if ((sieve[k]) && (sieve[k + 2]) && (sieve[k + 6]) && (sieve[k + 8]))
- quadprimes[m++] = start + k;
-
- }
- }
-
- void
- Init (void)
- {
- struct timeval start, end;
- double timeuse;
-
- gettimeofday (&start, NULL);
- InitPrimes ();
- InitSieve ();
- Sieve ();
- StoreSieveResult ();
-
- InitQuadPrimes ();
- SearchQuadSieve ();
- gettimeofday (&end, NULL);
-
- timeuse =
- 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;
- timeuse /= 1000000;
-
- printf ("Time use:%8.6f: %\n", timeuse);
-
- }
-
- void
- product (mpz_t r, unsigned long p[], unsigned long max)
- {
- unsigned long i;
- mpz_set_ui (r, 1);
-
- if (max < 2)
- return;
-
- for (i = 0; primes[i] <= max; i++)
- mpz_mul_ui (r, r, p[i]);
- }
-
- //状态文件分三行,分别存储A, B, C的数值
- void
- LoadStatus (void)
- {
- FILE *fstatus;
- fstatus = fopen ("quadprimes.status", "r+t");
- if (fstatus == NULL)
- {
- printf ("读取状态文件失败。\n");
- exit (1);
- }
- fscanf (fstatus, "%u%u%u", &A, &B, &C);
- fclose (fstatus);
- }
-
- void
- SaveStatus (void)
- {
- FILE *fstatus;
- fstatus = fopen ("quadprimes.status", "w+t");
- if (fstatus == NULL)
- {
- printf ("存储状态文件失败。\n");
- exit (1);
- }
- fprintf (fstatus, "%u\n%u\n%u\n", A, B, C);
- fclose (fstatus);
- }
-
- void
- SaveLog (void)
- {
- FILE *flog;
- flog = fopen ("quadprimes.log", "a+t");
- if (flog == NULL)
- {
- printf ("存储日志文件失败。\n");
- exit (1);
- }
- fprintf (flog, "%u %u %u\n", A, B, C);
- printf ("%u %u %u\n", A, B, C);
- fclose (flog);
-
- }
-
- unsigned long SearchQuadPrime(unsigned long p)
- {
- unsigned long k;
- for (k = 0; k < 4768; k ++)
- if (quadprimes[k] >= p)
- return (k);
- return (0);
- }
-
- void
- Test (void)
- {
- unsigned long m, k;
- mpz_t b0, b, p1, p2, p6, p8;
- LoadStatus ();
- mpz_init (b0);
- mpz_init(b);
- mpz_init (p1);
- mpz_init (p2);
- mpz_init (p6);
- mpz_init (p8);
-
- product (b0, primes, B);
- k = SearchQuadPrime(C);
- C = quadprimes[k];
- mpz_mul_ui (b, b0, A);
- mpz_add_ui (p1, b, C);
- m = 0;
- for (;;)
- {
- if (mpz_probab_prime_p (p1, 1))
- {
- mpz_add_ui (p2, p1, 2);
- if (mpz_probab_prime_p (p2, 1))
- {
- mpz_add_ui (p6, p1, 6);
- if (mpz_probab_prime_p (p6, 1))
- {
- mpz_add_ui (p8, p1, 8);
- if (mpz_probab_prime_p (p8, 1))
- SaveLog ();
- }
- }
- }
-
- //
- m ++;
- if (m > 100)
- {
- SaveStatus ();
- m = 0;
- }
- k ++;
- if (k >= 4768)
- {
- k = SearchQuadPrime(B);
- C = quadprimes[k];
- A ++;
- if (A == 0)
- {
- SaveLog();
- exit(2);
- }
- else
- {
- mpz_add(b, b, b0);
- mpz_add_ui(p1, b, C);
- }
- }
- else
- {
- C = quadprimes[k];
- mpz_add_ui(p1, b, C);
- }
- }
- mpz_clear (b);
- mpz_clear(b0);
- mpz_clear (p1);
- mpz_clear (p2);
- mpz_clear (p6);
- mpz_clear (p8);
- }
-
- int main (void)
- {
- unsigned long a, c;
-
- Init ();
-
- Test ();
- // for (a = 0; a < 4800; a++)
- // if (quadprimes[a])
- // printf ("%6u ", quadprimes[a]);
- // printf ("\n");
- return 0;
- }
复制代码 |
|