1 /* factor -- print prime factors of n.
2 Copyright (C) 1986-2012 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 /* Written by Paul Rubin <phr@ocf.berkeley.edu>.
18 Adapted for GNU, fixed to factor UINT_MAX by Jim Meyering.
19 Arbitrary-precision code adapted by James Youngman from Torbjörn
20 Granlund's factorize.c, from GNU MP version 4.2.2.
27 #include <sys/types.h>
37 #include "readtokens.h"
40 /* The official name of this program (e.g., no 'g' prefix). */
41 #define PROGRAM_NAME "factor"
43 #define AUTHORS proper_name ("Paul Rubin")
45 /* Token delimiters when reading from a file. */
48 static bool verbose
= false;
51 static mpz_t
*factor
= NULL
;
52 static size_t nfactors_found
= 0;
53 static size_t nfactors_allocated
= 0;
56 debug (char const *fmt
, ...)
62 vfprintf (stderr
, fmt
, ap
);
70 if (nfactors_found
== nfactors_allocated
)
71 factor
= X2NREALLOC (factor
, &nfactors_allocated
);
72 mpz_init (factor
[nfactors_found
]);
73 mpz_set (factor
[nfactors_found
], n
);
78 emit_ul_factor (unsigned long int i
)
88 factor_using_division (mpz_t t
, unsigned int limit
)
93 static unsigned int const add
[] = {4, 2, 4, 2, 4, 6, 2, 6};
94 unsigned int const *addv
= add
;
95 unsigned int failures
;
97 debug ("[trial division (%u)] ", limit
);
102 f
= mpz_scan1 (t
, 0);
103 mpz_div_2exp (t
, t
, f
);
112 mpz_tdiv_qr_ui (q
, r
, t
, 3);
113 if (mpz_cmp_ui (r
, 0) != 0)
121 mpz_tdiv_qr_ui (q
, r
, t
, 5);
122 if (mpz_cmp_ui (r
, 0) != 0)
131 while (mpz_cmp_ui (t
, 1) != 0)
133 mpz_tdiv_qr_ui (q
, r
, t
, f
);
134 if (mpz_cmp_ui (r
, 0) != 0)
137 if (mpz_cmp_ui (q
, f
) < 0)
141 if (failures
> limit
)
157 factor_using_pollard_rho (mpz_t n
, int a_int
)
165 debug ("[pollard-rho (%d)] ", a_int
);
171 mpz_init_set_si (a
, a_int
);
172 mpz_init_set_si (y
, 2);
173 mpz_init_set_si (x
, 2);
174 mpz_init_set_si (x1
, 2);
177 mpz_init_set_ui (P
, 1);
180 while (mpz_cmp_ui (n
, 1) != 0)
183 mpz_mul (x
, x
, x
); mpz_add (x
, x
, a
); mpz_mod (x
, x
, n
);
185 mpz_sub (t1
, x1
, x
); mpz_mul (t2
, P
, t1
); mpz_mod (P
, t2
, n
);
191 if (mpz_cmp_ui (g
, 1) != 0)
201 if (mpz_cmp_ui (g
, 1) != 0)
208 for (i
= 0; i
< k
; i
++)
210 mpz_mul (x
, x
, x
); mpz_add (x
, x
, a
); mpz_mod (x
, x
, n
);
218 mpz_mul (y
, y
, y
); mpz_add (y
, y
, a
); mpz_mod (y
, y
, n
);
219 mpz_sub (t1
, x1
, y
); mpz_gcd (g
, t1
, n
);
221 while (mpz_cmp_ui (g
, 1) == 0);
223 mpz_div (n
, n
, g
); /* divide by g, before g is overwritten */
225 if (!mpz_probab_prime_p (g
, 3))
230 mpn_random (&a_limb
, (mp_size_t
) 1);
231 a_int
= (int) a_limb
;
233 while (a_int
== -2 || a_int
== 0);
235 debug ("[composite factor--restarting pollard-rho] ");
236 factor_using_pollard_rho (g
, a_int
);
245 if (mpz_probab_prime_p (n
, 3))
265 debug (char const *fmt ATTRIBUTE_UNUSED
, ...)
271 /* The maximum number of factors, including -1, for negative numbers. */
272 #define MAX_N_FACTORS (sizeof (uintmax_t) * CHAR_BIT)
274 /* The trial divisor increment wheel. Use it to skip over divisors that
275 are composites of 2, 3, 5, 7, or 11. The part from WHEEL_START up to
276 WHEEL_END is reused periodically, while the "lead in" is used to test
277 for those primes and to jump onto the wheel. For more information, see
278 http://www.utm.edu/research/primes/glossary/WheelFactorization.html */
280 #include "wheel-size.h" /* For the definition of WHEEL_SIZE. */
281 static const unsigned char wheel_tab
[] =
286 #define WHEEL_START (wheel_tab + WHEEL_SIZE)
287 #define WHEEL_END (wheel_tab + ARRAY_CARDINALITY (wheel_tab))
292 factor_wheel (uintmax_t n0
, size_t max_n_factors
, uintmax_t *factors
)
294 uintmax_t n
= n0
, d
, q
;
295 size_t n_factors
= 0;
296 unsigned char const *w
= wheel_tab
;
301 /* The exit condition in the following loop is correct because
302 any time it is tested one of these 3 conditions holds:
305 (3) n is composite but has no factors less than d.
306 If (1) or (2) obviously the right thing happens.
307 If (3), then since n is composite it is >= d^2. */
315 assert (n_factors
< max_n_factors
);
316 factors
[n_factors
++] = d
;
326 if (n
!= 1 || n0
== 1)
328 assert (n_factors
< max_n_factors
);
329 factors
[n_factors
++] = n
;
335 /* Single-precision factoring */
337 print_factors_single (uintmax_t n
)
339 uintmax_t factors
[MAX_N_FACTORS
];
340 size_t n_factors
= factor_wheel (n
, MAX_N_FACTORS
, factors
);
342 char buf
[INT_BUFSIZE_BOUND (uintmax_t)];
344 printf ("%s:", umaxtostr (n
, buf
));
345 for (i
= 0; i
< n_factors
; i
++)
346 printf (" %s", umaxtostr (factors
[i
], buf
));
352 mpcompare (const void *av
, const void *bv
)
354 mpz_t
*const *a
= av
;
355 mpz_t
*const *b
= bv
;
356 return mpz_cmp (**a
, **b
);
360 sort_and_print_factors (void)
365 faclist
= xcalloc (nfactors_found
, sizeof *faclist
);
366 for (i
= 0; i
< nfactors_found
; ++i
)
368 faclist
[i
] = &factor
[i
];
370 qsort (faclist
, nfactors_found
, sizeof *faclist
, mpcompare
);
372 for (i
= 0; i
< nfactors_found
; ++i
)
375 mpz_out_str (stdout
, 10, *faclist
[i
]);
386 for (i
= 0; i
< nfactors_found
; ++i
)
388 mpz_clear (factor
[i
]);
390 /* Don't actually free factor[] because in the case where we are
391 reading numbers from stdin, we may be about to use it again. */
395 /* Arbitrary-precision factoring */
397 print_factors_multi (mpz_t t
)
399 mpz_out_str (stdout
, 10, t
);
402 if (mpz_sgn (t
) != 0)
404 /* Set the trial division limit according to the size of t. */
405 size_t n_bits
= mpz_sizeinbase (t
, 2);
406 unsigned int division_limit
= MIN (n_bits
, 1000);
407 division_limit
*= division_limit
;
409 factor_using_division (t
, division_limit
);
411 if (mpz_cmp_ui (t
, 1) != 0)
413 debug ("[is number prime?] ");
414 if (mpz_probab_prime_p (t
, 3))
417 factor_using_pollard_rho (t
, 1);
422 sort_and_print_factors ();
428 /* Emit the factors of the indicated number. If we have the option of using
429 either algorithm, we select on the basis of the length of the number.
430 For longer numbers, we prefer the MP algorithm even if the native algorithm
431 has enough digits, because the algorithm is better. The turnover point
432 depends on the value. */
434 print_factors (char const *s
)
437 strtol_error err
= xstrtoumax (s
, NULL
, 10, &n
, "");
440 enum { GMP_TURNOVER_POINT
= 100000 };
442 if (err
== LONGINT_OVERFLOW
443 || (err
== LONGINT_OK
&& GMP_TURNOVER_POINT
<= n
))
447 if (gmp_sscanf (s
, "%Zd", t
) == 1)
449 debug ("[%s]", _("using arbitrary-precision arithmetic"));
450 print_factors_multi (t
);
453 err
= LONGINT_INVALID
;
460 debug ("[%s]", _("using single-precision arithmetic"));
461 print_factors_single (n
);
464 case LONGINT_OVERFLOW
:
465 error (0, 0, _("%s is too large"), quote (s
));
469 error (0, 0, _("%s is not a valid positive integer"), quote (s
));
476 VERBOSE_OPTION
= CHAR_MAX
+ 1
479 static struct option
const long_options
[] =
481 {"verbose", no_argument
, NULL
, VERBOSE_OPTION
},
482 {GETOPT_HELP_OPTION_DECL
},
483 {GETOPT_VERSION_OPTION_DECL
},
490 if (status
!= EXIT_SUCCESS
)
495 Usage: %s [NUMBER]...\n\
498 program_name
, program_name
);
500 Print the prime factors of each specified integer NUMBER. If none\n\
501 are specified on the command line, read them from standard input.\n\
504 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
505 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
506 emit_ancillary_info ();
515 token_buffer tokenbuffer
;
517 init_tokenbuffer (&tokenbuffer
);
521 size_t token_length
= readtoken (stdin
, DELIM
, sizeof (DELIM
) - 1,
523 if (token_length
== (size_t) -1)
525 ok
&= print_factors (tokenbuffer
.buffer
);
527 free (tokenbuffer
.buffer
);
533 main (int argc
, char **argv
)
538 initialize_main (&argc
, &argv
);
539 set_program_name (argv
[0]);
540 setlocale (LC_ALL
, "");
541 bindtextdomain (PACKAGE
, LOCALEDIR
);
542 textdomain (PACKAGE
);
544 atexit (close_stdout
);
546 while ((c
= getopt_long (argc
, argv
, "", long_options
, NULL
)) != -1)
554 case_GETOPT_HELP_CHAR
;
556 case_GETOPT_VERSION_CHAR (PROGRAM_NAME
, AUTHORS
);
559 usage (EXIT_FAILURE
);
569 for (i
= optind
; i
< argc
; i
++)
570 if (! print_factors (argv
[i
]))
576 exit (ok
? EXIT_SUCCESS
: EXIT_FAILURE
);