randnum.c (1940B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <err.h> 4 #include <limits.h> 5 #include <string.h> 6 #include <math.h> 7 #include <unistd.h> 8 #include <sys/time.h> 9 10 #include "util.h" 11 12 static void 13 usage(void) 14 { 15 errx(1, "usage: randnum [-d delimstr] [-n] [-N num] " 16 "[-p prec] [-s seed] " 17 "[[min_val] max_val]"); 18 } 19 20 int 21 main(int argc, char *argv[]) 22 { 23 int i, ch, s = 0, prec = 17, finalnl = 1; 24 long seed, n = 1; 25 double minv = 0.0, maxv = 1.0; 26 char *delimstr = "\n"; 27 const char *errstr; 28 struct timeval t1; 29 30 if (pledge("stdio", NULL) == -1) 31 err(2, "pledge"); 32 33 while ((ch = getopt(argc, argv, "d:nN:p:s:")) != -1) { 34 switch (ch) { 35 case 'd': 36 delimstr = optarg; 37 break; 38 case 'n': 39 finalnl = 0; 40 break; 41 case 'N': 42 n = strtonum(optarg, 0, LONG_MAX, &errstr); 43 if (errstr != NULL) 44 errx(1, "bad num value, %s: %s", errstr, optarg); 45 break; 46 case 'p': 47 prec = strtonum(optarg, 0, INT_MAX, &errstr); 48 if (errstr != NULL) 49 errx(1, "bad precision value, %s: %s", errstr, optarg); 50 break; 51 case 's': 52 seed = strtonum(optarg, 0, INT_MAX, &errstr); 53 if (errstr != NULL) 54 errx(1, "bad seed value, %s: %s", errstr, optarg); 55 break; 56 default: 57 usage(); 58 } 59 } 60 argc -= optind; 61 argv += optind; 62 63 if (argc > 2) 64 usage(); 65 else if (argc == 2) { 66 if (!sscanf(argv[0], "%lf", &minv)) 67 errx(1, "bad minv value: %s", argv[0]); 68 if (!sscanf(argv[1], "%lf", &maxv)) 69 errx(1, "bad maxv value: %s", argv[1]); 70 } else if (argc == 1) 71 if (!sscanf(argv[0], "%lf", &maxv)) 72 errx(1, "bad maxv value: %s", argv[0]); 73 74 if (s) 75 #ifdef __OpenBSD__ 76 srand48_deterministic(seed); 77 #else 78 srand48(seed); 79 else { 80 gettimeofday(&t1, NULL); 81 srand48(t1.tv_sec * t1.tv_usec); /* Caveat: identical seed for each ms */ 82 } 83 #endif 84 85 for (i = 0; i < n; i++) { 86 printf("%.*g", prec, drand48() * (maxv - minv) + minv); 87 if (i < n - 1) 88 fputs(delimstr, stdout); 89 } 90 if (finalnl) 91 putchar('\n'); 92 93 return 0; 94 }