|
|
1.1 ! root 1: /* ! 2: * Factor prints out the prime factorization of numbers. If there are ! 3: * any arguments, then it factors these. If there are no arguments, ! 4: * then it reads stdin until either EOF or the number zero or a non-numeric ! 5: * non-white-space character. Since factor does all of its calculations ! 6: * in double format, the largest number which can be handled is quite ! 7: * large. ! 8: */ ! 9: #include <stdio.h> ! 10: #include <math.h> ! 11: #include <ctype.h> ! 12: ! 13: ! 14: #define NUL '\0' ! 15: #define ERROR 0x10 /* largest input base */ ! 16: #define MAXNUM 200 /* max number of chars in number */ ! 17: ! 18: ! 19: main(argc, argv) ! 20: int argc; ! 21: register char *argv[]; ! 22: { ! 23: register char *chp; ! 24: double n; ! 25: double atod(); ! 26: char *getnum(); ! 27: ! 28: if (argc != 1) ! 29: while ((chp=*++argv) != NULL && (n=atod(chp)) != 0) ! 30: factor(n); ! 31: else ! 32: while ((chp=getnum()) != NULL && (n=atod(chp)) != 0) ! 33: factor(n); ! 34: return (0); ! 35: } ! 36: ! 37: ! 38: die(str) ! 39: char *str; ! 40: { ! 41: fprintf(stderr, "%r\n", &str); ! 42: exit(1); ! 43: } ! 44: ! 45: usage() ! 46: { ! 47: die("usage: factor [number number ...]"); ! 48: } ! 49: ! 50: ! 51: char * ! 52: getnum() ! 53: { ! 54: register char *chp, ! 55: ch; ! 56: static char res[MAXNUM+1]; ! 57: ! 58: do { ! 59: ch = getchar(); ! 60: } while (isascii(ch) && isspace(ch)); ! 61: if (!isascii(ch) || todigit(ch) == ERROR) ! 62: return (NULL); ! 63: for (chp=res; isascii(ch) && !isspace(ch); ch=getchar()) ! 64: if (chp < &res[MAXNUM]) ! 65: *chp++ = ch; ! 66: if (chp >= &res[MAXNUM]) ! 67: die("Number too big"); ! 68: *chp++ = NUL; ! 69: return (res); ! 70: } ! 71: ! 72: ! 73: /* ! 74: * Atod converts the string `num' to a double and returns the value. ! 75: * Note, that if there is a non-digit in the string, or if there is ! 76: * an overflow, then it exits with an appropriate error message. ! 77: * Also note that atod accepts leading zero for octal and leading ! 78: * 0x for hexidecimal, and that in the latter case, a-f and A-F are ! 79: * both accepted as digits. ! 80: */ ! 81: double ! 82: atod(num) ! 83: char *num; ! 84: { ! 85: register char *str; ! 86: register int i; ! 87: double res = 0, ! 88: base = 10; ! 89: ! 90: str = num; ! 91: i = *str++; ! 92: if (i == '0') ! 93: if ((i=*str++) == 'x') { ! 94: i = *str++; ! 95: base = 0x10; ! 96: } else ! 97: base = 010; ! 98: for (; i != '\0'; i=*str++) { ! 99: i = todigit(i); ! 100: if (i >= base) ! 101: die("bad number `%s'", num); ! 102: res = res * base + i; ! 103: if (res+1 == res) ! 104: die("Number too big `%s'", num); ! 105: } ! 106: return (res); ! 107: } ! 108: ! 109: ! 110: /* ! 111: * Todigit converts the char `ch' to an integer equivalent, assuming ! 112: * that `ch' is a digit or `a'-`f' or `A'-`F'. If this is not true, ! 113: * then it returns ERROR. ! 114: */ ! 115: todigit(ch) ! 116: register int ch; ! 117: { ! 118: if (!isascii(ch)) ! 119: return (ERROR); ! 120: if (isdigit(ch)) ! 121: return (ch - '0' + 0); ! 122: if (isupper(ch)) ! 123: ch = tolower(ch); ! 124: if ('a' <= ch && ch <= 'f') ! 125: return (ch - 'a' + 0xa); ! 126: return (ERROR); ! 127: } ! 128: ! 129: ! 130: /* ! 131: * Factor is the routine that actually factors the double `n'. ! 132: * It writes the prime factors to standard output. ! 133: */ ! 134: factor(n) ! 135: double n; ! 136: { ! 137: double temp, ! 138: limit, ! 139: try; ! 140: ! 141: while (n > 1 && modf(n/2, &temp) == 0) { ! 142: printf("2 "); ! 143: n = temp; ! 144: } ! 145: limit = sqrt(n); ! 146: for (try=3; try <= limit; try += 2) { ! 147: if (modf(n/try, &temp) != 0) ! 148: continue; ! 149: do { ! 150: printf("%.0f ", try); ! 151: n = temp; ! 152: } while (modf(n/try, &temp) == 0); ! 153: limit = sqrt(n); ! 154: } ! 155: if (n > 1) ! 156: printf("%.0f", n); ! 157: putchar('\n'); ! 158: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.