|
|
1.1 ! root 1: /* ! 2: * File: nlp.c ! 3: * ! 4: * Purpose: find next lower prime from a number ! 5: * Only use for this module now is calculating NHASH given NBUF. ! 6: * ! 7: * Compile -DTEST=1 for test version. ! 8: * ! 9: * Revised: Wed Aug 4 12:44:29 1993 CDT ! 10: */ ! 11: ! 12: /* ! 13: * ---------------------------------------------------------------------- ! 14: * Includes. ! 15: */ ! 16: #include <common/_tricks.h> ! 17: #include <common/ccompat.h> ! 18: #include <common/xdebug.h> ! 19: ! 20: /* ! 21: * ---------------------------------------------------------------------- ! 22: * Definitions. ! 23: * Constants. ! 24: * Macros with argument lists. ! 25: * Typedefs. ! 26: * Enums. ! 27: */ ! 28: #if TEST ! 29: #include <stdio.h> ! 30: #define TESTPRINT(args) (printf args) ! 31: int main __PROTO((void)); ! 32: #else ! 33: #define TESTPRINT(args) ! 34: #endif ! 35: ! 36: /* ! 37: * ---------------------------------------------------------------------- ! 38: * Functions. ! 39: * Import Functions. ! 40: * Export Functions. ! 41: * Local Functions. ! 42: */ ! 43: unsigned int nlp __PROTO ((unsigned int num)); ! 44: ! 45: __LOCAL__ int isprime __PROTO ((unsigned int num)); ! 46: __LOCAL__ unsigned int isqrt __PROTO ((unsigned int num)); ! 47: ! 48: /* ! 49: * ---------------------------------------------------------------------- ! 50: * Global Data. ! 51: * Import Variables. ! 52: * Export Variables. ! 53: * Local Variables. ! 54: */ ! 55: ! 56: /* ! 57: * ---------------------------------------------------------------------- ! 58: * Code. ! 59: */ ! 60: ! 61: /************************************************************************ ! 62: * nlp ! 63: * ! 64: * Return the next prime strictly less than the given argument. ! 65: * Return 0 if the argument is 0, 1, or 2. ! 66: ***********************************************************************/ ! 67: #if __USE_PROTO__ ! 68: unsigned int nlp (unsigned int num) ! 69: #else ! 70: unsigned int ! 71: nlp (num) ! 72: unsigned int num; ! 73: #endif ! 74: { ! 75: unsigned int ret; ! 76: ! 77: switch(num) { ! 78: case 0: ! 79: case 1: ! 80: case 2: ! 81: ret = 0; ! 82: break; ! 83: default: ! 84: for (num--; num > 2; num--) { ! 85: if (isprime(num)) { ! 86: break; ! 87: } ! 88: } ! 89: ret = num; ! 90: } ! 91: ! 92: return ret; ! 93: } ! 94: ! 95: /************************************************************************ ! 96: * isprime ! 97: * ! 98: * Return nonzero if the argument is prime, else return 0. ! 99: * Return 0 if the argument is 0 or 1. ! 100: ***********************************************************************/ ! 101: #if __USE_PROTO__ ! 102: __LOCAL__ int isprime (unsigned int num) ! 103: #else ! 104: __LOCAL__ int ! 105: isprime (num) ! 106: unsigned int num; ! 107: #endif ! 108: { ! 109: int ret = 1; ! 110: unsigned int nsqrt = isqrt(num); ! 111: unsigned int f; ! 112: ! 113: switch(num) { ! 114: case 0: ! 115: case 1: ! 116: ret = 0; ! 117: break; ! 118: default: ! 119: if ((num & 1) == 0) ! 120: ret = 0; ! 121: else for (f = 3; f <= nsqrt; f++) { ! 122: if ((num % f) == 0) { ! 123: ret = 0; ! 124: break; ! 125: } ! 126: } ! 127: } ! 128: ! 129: TESTPRINT(("isprime(%u) = %d\n", num, ret)); ! 130: ! 131: return ret; ! 132: } ! 133: ! 134: /************************************************************************ ! 135: * isqrt ! 136: * ! 137: * Return the smallet integer greater than or equal to the square root ! 138: * of the argument. ! 139: ***********************************************************************/ ! 140: #if __USE_PROTO__ ! 141: __LOCAL__ unsigned int isqrt (unsigned int num) ! 142: #else ! 143: __LOCAL__ unsigned int ! 144: isqrt (num) ! 145: unsigned int num; ! 146: #endif ! 147: { ! 148: unsigned int ret; ! 149: int guess; ! 150: int guess2; ! 151: int loopct; ! 152: ! 153: switch(num) { ! 154: case 0: ! 155: case 1: ! 156: loopct = 0; ! 157: ret = num; ! 158: break; ! 159: default: ! 160: /* Newton's method, adapted for integers. */ ! 161: guess = num >> 1; ! 162: ! 163: /* Use binary to get quick first guess. */ ! 164: guess = 1 << (__MOST_BIT_UINT(num) / 2); ! 165: ! 166: for (loopct = 0; loopct < 32; loopct++) { ! 167: guess2 = num / guess; ! 168: ! 169: TESTPRINT(("g1 = %u g2 = %u\n", guess, guess2)); ! 170: ! 171: if (guess >= guess2) { ! 172: ret = guess; ! 173: if (guess - guess2 <= 1) { ! 174: break; ! 175: } ! 176: } else { ! 177: ret = guess2; ! 178: if (guess2 - guess <= 1) { ! 179: break; ! 180: } ! 181: } ! 182: guess = (guess2 + guess) / 2; ! 183: } ! 184: if (ret * ret < num) ! 185: ret++; ! 186: } ! 187: ! 188: TESTPRINT(("isqrt(%d) = %d loopct = %d\n", num, ret, loopct)); ! 189: ! 190: return ret; ! 191: } ! 192: ! 193: #if TEST ! 194: #if __USE_PROTO ! 195: int main(void) ! 196: #else ! 197: int main() ! 198: #endif ! 199: { ! 200: unsigned int num; ! 201: ! 202: for (;;) { ! 203: printf("enter a number: "); ! 204: if (scanf("%u", &num)) ! 205: printf("Next lower prime from %u is %u\n", ! 206: num, nlp(num)); ! 207: else ! 208: break; ! 209: } ! 210: ! 211: return 0; ! 212: } ! 213: #endif /* TEST */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.