1 |
//$Header$ |
2 |
// |
3 |
//******************************************************************************** |
4 |
//Copyright (C) 2003 David T. Ashley |
5 |
//******************************************************************************** |
6 |
//This program or source file is free software; you can redistribute it and/or |
7 |
//modify it under the terms of the GNU General Public License as published by |
8 |
//the Free Software Foundation; either version 2 of the License, or (at your |
9 |
//option) any later version. |
10 |
// |
11 |
//This program or source file is distributed in the hope that it will |
12 |
//be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 |
//GNU General Public License for more details. |
15 |
// |
16 |
//You may have received a copy of the GNU General Public License |
17 |
//along with this program; if not, write to the Free Software |
18 |
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 |
//******************************************************************************** |
20 |
// |
21 |
//This module uses the GMP libary function: |
22 |
// |
23 |
// mpz_probab_prime_p() |
24 |
// |
25 |
//To make a probabilistic assessment of whether an integer is most likely |
26 |
//prime, definitely composite, etc. This module is just a direct interface |
27 |
//to the GMP function cited above. |
28 |
// |
29 |
//INPUT PARAMETERS |
30 |
//---------------- |
31 |
//The subfunction accepts two parameters, the integers whose primality is to be |
32 |
//assessed, and the number of reps (passed directly to the GMP function). |
33 |
//Naturally, the integers should be positive. Invalid integers are assigned |
34 |
//defaults. It is the responsibility of the calling script to do whatever |
35 |
//sanity checking is desired. |
36 |
// |
37 |
//OUTPUT RESULTS |
38 |
//-------------- |
39 |
//The notation below gives the outputs of the program. In some cases, [i] notation |
40 |
//is used to indicate line numbers. |
41 |
// |
42 |
//[01] An overall success or failure code for the operation. Valid responses |
43 |
// are: |
44 |
// S : Success (for this subfunction, the only possible outcome). |
45 |
// |
46 |
//[02] The fully normalized first integer entered. This means it has been |
47 |
// stripped of all weird characters, etc., and also perhaps assigned |
48 |
// a default value if the original parameter wasn't acceptable. |
49 |
// This can be used by the PHP script to repopulate form boxes. |
50 |
//[03] The fully normalized second integer entered. |
51 |
//[04] The output from the GMP function. Semantics are: |
52 |
// 2 -- definitely prime. |
53 |
// 1 -- probably prime. |
54 |
// 0 -- definitely composite. |
55 |
//[05] "S", indicating success. |
56 |
// |
57 |
//Note that this subfunction will always return exactly five lines, |
58 |
//and the first and last line will be "S". |
59 |
// |
60 |
//The return value (exit code) from this subfunction is always 0. |
61 |
// |
62 |
|
63 |
#define MODULE_SUBFUNC_GMP_PROB_PRIME |
64 |
|
65 |
#include <assert.h> |
66 |
#include <ctype.h> |
67 |
#include <stddef.h> |
68 |
#include <stdio.h> |
69 |
#include <stdlib.h> |
70 |
#include <string.h> |
71 |
#include <time.h> |
72 |
|
73 |
#include <gmp.h> |
74 |
|
75 |
#include "auxfuncs.h" |
76 |
#include "subfunc_gmp_prob_prime.h" |
77 |
|
78 |
|
79 |
int SUBFUNC_GMP_PROB_PRIME_main(int argc, char *argv[]) |
80 |
{ |
81 |
//Normalized first and second parameters (the integers). |
82 |
char *arg1; |
83 |
char *arg2; |
84 |
|
85 |
//GMP types to maintain the algorithm. |
86 |
int nreps_native; |
87 |
mpz_t number_to_test, nreps_mpz; |
88 |
|
89 |
//Result from the GMP. |
90 |
int gmp_result; |
91 |
|
92 |
//There must be an acceptable number of command-line arguments. If not, |
93 |
//abort the progam with phony data. |
94 |
if (argc != 4) |
95 |
{ |
96 |
printf("S\n2\n5\n2\nS\n"); |
97 |
return(0); |
98 |
} |
99 |
|
100 |
//Copy the command-line arguments to a safe place where we can manipulate them. |
101 |
//Leave 2 characters of space in case we assign a "0". |
102 |
arg1 = (char *)malloc((AUXFUNCS_size_t_max(1, strlen(argv[2])) + 1) * sizeof(char)); |
103 |
arg2 = (char *)malloc((AUXFUNCS_size_t_max(1, strlen(argv[3])) + 1) * sizeof(char)); |
104 |
if ((arg1 == NULL) || (arg2 == NULL)) |
105 |
{ |
106 |
printf("S\n2\n5\n2\nS\n"); |
107 |
return(0); |
108 |
} |
109 |
strcpy(arg1, argv[2]); |
110 |
strcpy(arg2, argv[3]); |
111 |
|
112 |
//Strip all of the non-digit trash out of the arguments. |
113 |
AUXFUNCS_remove_non_digits(arg1); |
114 |
AUXFUNCS_remove_non_digits(arg2); |
115 |
|
116 |
//Remove all leading zeros from both arguments. |
117 |
AUXFUNCS_remove_leading_zeros(arg1); |
118 |
AUXFUNCS_remove_leading_zeros(arg2); |
119 |
|
120 |
//If either argument is zero length, fill it in with 0. |
121 |
if (!strlen(arg1)) |
122 |
strcpy(arg1, "0"); |
123 |
if (!strlen(arg2)) |
124 |
strcpy(arg2, "0"); |
125 |
|
126 |
//We are not allowed to have 0's in this function, so |
127 |
//abort on zeros. Also, we can't have 1 for a number to check, |
128 |
//as 1 is neither prime nor composite. |
129 |
if ((!strcmp(arg1, "0")) || (!strcmp(arg2, "0")) || (!strcmp(arg1, "1"))) |
130 |
{ |
131 |
printf("S\n2\n5\n2\nS\n"); |
132 |
return(0); |
133 |
} |
134 |
|
135 |
//If either argument exceeds 10000 digits, abort. |
136 |
if ((strlen(arg1)>10000) || (strlen(arg2) > 10000)) |
137 |
{ |
138 |
printf("S\n2\n5\n2\nS\n"); |
139 |
return(0); |
140 |
} |
141 |
|
142 |
//Initialize all of the GMP variables. |
143 |
mpz_init(number_to_test); |
144 |
mpz_init(nreps_mpz); |
145 |
|
146 |
//Assign a and b to initial values. |
147 |
mpz_set_str(number_to_test, arg1, 10); |
148 |
mpz_set_str(nreps_mpz, arg2, 10); |
149 |
|
150 |
//We don't want to allow any more than 5000 repetitions for that |
151 |
//parameter. So, if it is larger than 5000, whack it down. |
152 |
if (mpz_cmp_d(nreps_mpz, (double)5000) > 0) |
153 |
mpz_set_str(nreps_mpz, "5000", 10); |
154 |
|
155 |
//Extract the arbitrary length value of the number of reps into |
156 |
//a normal integer. |
157 |
nreps_native = mpz_get_si(nreps_mpz); |
158 |
|
159 |
//Run the GMP library function to guess at primality and get the result |
160 |
//back. |
161 |
gmp_result = mpz_probab_prime_p(number_to_test, nreps_native); |
162 |
|
163 |
//Now, write the output block. |
164 |
printf("S\n"); |
165 |
mpz_out_str(stdout, 10, number_to_test); |
166 |
printf("\n"); |
167 |
mpz_out_str(stdout, 10, nreps_mpz); |
168 |
printf("\n"); |
169 |
printf("%d\n", gmp_result); |
170 |
printf("S\n"); |
171 |
|
172 |
//Always return 0. |
173 |
return(0); |
174 |
} |
175 |
|
176 |
//******************************************************************************** |
177 |
// $Log: subfunc_gmp_prob_prime.c,v $ |
178 |
// Revision 1.4 2003/07/01 03:46:58 dtashley |
179 |
// Edits towards working continued fraction best rational approximation |
180 |
// functionality. |
181 |
// |
182 |
// Revision 1.3 2003/04/17 20:02:05 dtashley |
183 |
// License text for the GPL added. All source files are now under the GPL, |
184 |
// after some discussion on the GMP list. |
185 |
// |
186 |
// Revision 1.2 2003/04/14 23:27:01 dtashley |
187 |
// Subfunction GMP_PROB_PRIME finished. |
188 |
// |
189 |
// Revision 1.1 2003/04/14 22:35:23 dtashley |
190 |
// Initial checkin. |
191 |
//******************************************************************************** |
192 |
// End of SUBFUNC_GMP_PROB_PRIME.C. |
193 |
//******************************************************************************** |