comparison example/Miller_Rabin/ppe/Prime.cc @ 1242:9d37fa6bc1da draft

add Miller_Rabin
author Daichi Toma <amothic@gmail.com>
date Tue, 01 Nov 2011 19:01:13 +0900
parents
children cd50c48f45e7
comparison
equal deleted inserted replaced
1241:b96b1604ab85 1242:9d37fa6bc1da
1 #include <stdio.h>
2 #include "SchedTask.h"
3 #include "Prime.h"
4 #include "Func.h"
5
6 typedef unsigned long long U64;
7
8 static U64 base[] = { 2, 3, 5, 7, 11 };
9 #define MRMAX 5
10
11 SchedDefineTask1(Prime, prime);
12
13 static U64
14 powMod(U64 base, U64 power, U64 mod)
15 {
16 U64 result = 1;
17
18 while (power > 0) {
19 if ( power & 1 == 1 ) {
20 result = (result * base) % mod;
21 }
22 base = ( base * base ) % mod;
23 power >>= 1;
24 }
25 return result;
26 }
27
28 static bool
29 millarRabin(U64 a, U64 s, U64 d, U64 n) {
30 U64 x = powMod(a, d, n);
31 if ( x == 1) return true;
32 for ( U64 r = 0; r < s; r++) {
33 if ( x == n-1 ) return true;
34 x = (x * x) % n;
35 }
36 return false;
37 }
38
39 static bool
40 isPrime(U64 n) {
41
42 if ( n <= 1 ) return false;
43
44 U64 d = n - 1;
45 U64 s = 0;
46
47 while( (d & 1) == 0 ) {
48 d >>= 1;
49 s++;
50 }
51
52 for ( int i = 0; i < MRMAX; i++ ) {
53 if ( n == base[i] ) return true;
54 if (!millarRabin(base[i], s, d, n)) return false;
55 }
56 return true;
57 }
58
59 static int
60 prime(SchedTask *smanager, void *rbuf, void *wbuf)
61 {
62 U64 start = (U64)smanager->get_param(0); /* 素数判定の開始地点 */
63 U64 end = (U64)smanager->get_param(1); /* 素数判定の終了地点 */
64 U64 range = end - start; /* 判定する範囲 */
65
66 /* 判定結果を収める配列を受け取る */
67 bool *output = (bool*)smanager->get_output(wbuf, 0);
68
69 /* 初期化 */
70 for (U64 i = 0; i < range; i++){
71 output[i] = true;
72 }
73
74 for (U64 i = start + 1,index = 0; index < range; i += 2, index++) {
75 if (!isPrime(i)) {
76 output[index] = false;
77 }
78 }
79 return 0;
80 }