• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* factor.c - Factor integers
2  *
3  * Copyright 2014 Rob Landley <rob@landley.net>
4  *
5  * No standard, but it's in coreutils
6 
7 USE_FACTOR(NEWTOY(factor, 0, TOYFLAG_USR|TOYFLAG_BIN))
8 
9 config FACTOR
10   bool "factor"
11   default y
12   help
13     usage: factor NUMBER...
14 
15     Factor integers.
16 */
17 
18 #include "toys.h"
19 
factor(char * s)20 static void factor(char *s)
21 {
22   unsigned long l, ll;
23 
24   for (;;) {
25     char *err = s;
26 
27     while(isspace(*s)) s++;
28     if (!*s) return;
29 
30     l = strtoul(s, &s, 0);
31     if (*s && !isspace(*s)) {
32       error_msg("%s: not integer", err);
33 
34       return;
35     }
36 
37     printf("%lu:", l);
38 
39     // Negative numbers have -1 as a factor
40     if (l < 0) {
41       printf(" -1");
42       l *= -1;
43     }
44 
45     // Nothing below 4 has factors
46     if (l < 4) {
47       printf(" %lu\n", l);
48       continue;
49     }
50 
51     // Special case factors of 2
52     while (l && !(l&1)) {
53       printf(" 2");
54       l >>= 1;
55     }
56 
57     // test odd numbers.
58     for (ll=3; ;ll += 2) {
59       long lll = ll*ll;
60 
61       if (lll>l || lll<ll) {
62         if (l>1) printf(" %lu", l);
63         break;
64       }
65       while (!(l%ll)) {
66         printf(" %lu", ll);
67         l /= ll;
68       }
69     }
70     xputc('\n');
71   }
72 }
73 
factor_main(void)74 void factor_main(void)
75 {
76   if (toys.optc) {
77     char **ss;
78 
79     for (ss = toys.optargs; *ss; ss++) factor(*ss);
80   } else for (;;) {
81     char *s = 0;
82     size_t len = 0;
83 
84     if (-1 == getline(&s, &len, stdin)) break;
85     factor(s);
86   }
87 }
88