common/config: Allow environment defined btrfs mkfs options
[xfstests-dev.git] / lib / random_range.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000 Silicon Graphics, Inc.
4  * All Rights Reserved.
5  */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <malloc.h>
10 #include "random_range.h"
11
12 /*
13  * Internal format of the range array set up by parse_range()
14  */
15
16 struct range {
17         int     min;
18         int     max;
19         int     mult;
20 };
21
22 /*
23  * parse_ranges() is a function to parse a comma-separated list of range
24  * tokens each having the following form:
25  *
26  *              num
27  *      or
28  *              min:max[:mult]
29  *
30  * any of the values may be blank (ie. min::mult, :max, etc.) and default
31  * values for missing arguments may be supplied by the caller.
32  *
33  * The special first form is short hand for 'num:num'.
34  *
35  * After parsing the string, the ranges are put into an array of integers,
36  * which is malloc'd by the routine.  The min, max, and mult entries of each
37  * range can be extracted from the array using the range_min(), range_max(),
38  * and range_mult() functions.
39  *
40  * It is the responsibility of the caller to free the space allocated by
41  * parse_ranges() - a single call to free() will free the space.
42  *
43  *      str             The string to parse - assumed to be a comma-separated
44  *                      list of tokens having the above format.
45  *      defmin          default value to plug in for min, if it is missing
46  *      defmax          default value to plug in for max, if it is missing     
47  *      defmult         default value to plug in for mult, if missing
48  *      parse_func      A user-supplied function pointer, which parse_ranges()
49  *                      can call to parse the min, max, and mult strings.  This
50  *                      allows for customized number formats.  The function
51  *                      MUST have the following prototype:
52  *                              parse_func(char *str, int *val)
53  *                      The function should return -1 if str cannot be parsed
54  *                      into an integer, or >= 0 if it was successfully 
55  *                      parsed.  The resulting integer will be stored in
56  *                      *val.  If parse_func is NULL, parse_ranges will parse
57  *                      the tokens in a manner consistent with the the sscanf
58  *                      %i format.
59  *      range_ptr       A user-supplied char **, which will be set to point
60  *                      at malloc'd space which holds the parsed range
61  *                      values.   If range_ptr is NULL, parse_ranges() just
62  *                      parses the string.  The data returned in range_ptr
63  *                      should not be processed directly - use the functions
64  *                      range_min(), range_max(), and range_mult() to access
65  *                      data for a given range.
66  *      errptr          user-supplied char ** which can be set to point to a
67  *                      static error string.  If errptr is NULL, it is ignored.
68  *
69  * parse_range() returns -1 on error, or the number of ranges parsed.
70  */
71
72 static int       str_to_int();
73 static long long divider(long long, long long, long long, long long);
74
75 int
76 parse_ranges(str, defmin, defmax, defmult, parse_func, rangeptr, errptr)
77 char    *str;
78 int     defmin;
79 int     defmax;
80 int     defmult;
81 int     (*parse_func)();
82 char    **rangeptr;
83 char    **errptr;
84 {
85         int             ncommas;
86         char            *tmpstr, *cp, *tok, *n1str, *n2str, *multstr;
87         struct range    *rp, *ranges;
88         static char     errmsg[256];
89
90         if (errptr != NULL) {
91                 *errptr = errmsg;
92         }
93
94         for (ncommas = 0, cp = str; *cp != '\0'; cp++) {
95                 if (*cp == ',') {
96                         ncommas++;
97                 }
98         }
99
100         if (parse_func == NULL) {
101                 parse_func = str_to_int;
102         }
103
104         tmpstr = strdup(str);
105         ranges = (struct range *)malloc((ncommas+1) * sizeof(struct range));
106         rp = ranges;
107
108         tok = strtok(tmpstr, ",");
109         while (tok != NULL) {
110                 n1str = tok;
111                 n2str = NULL;
112                 multstr = NULL;
113
114                 rp->min = defmin;
115                 rp->max = defmax;
116                 rp->mult = defmult;
117
118                 if ((cp = strchr(n1str, ':')) != NULL) {
119                         *cp = '\0';
120                         n2str = cp+1;
121
122                         if ((cp = strchr(n2str, ':')) != NULL) {
123                                 *cp = '\0';
124                                 multstr = cp+1;
125                         }
126                 }
127
128                 /*
129                  * Parse the 'min' field - if it is zero length (:n2[:mult]
130                  * format), retain the default value, otherwise, pass the
131                  * string to the parse function.
132                  */
133
134                 if ((int)strlen(n1str) > 0) {
135                         if ((*parse_func)(n1str, &rp->min) < 0) {
136                                 sprintf(errmsg, "error parsing string %s into an integer", n1str);
137                                 free(tmpstr);
138                                 free(ranges);
139                                 return -1;
140                         }
141                 }
142
143                 /*
144                  * Process the 'max' field - if one was not present (n1 format)
145                  * set max equal to min.  If the field was present, but 
146                  * zero length (n1: format), retain the default.  Otherwise
147                  * pass the string to the parse function.
148                  */
149
150                 if (n2str == NULL) {
151                         rp->max = rp->min;
152                 } else if ((int)strlen(n2str) > 0) {
153                         if ((*parse_func)(n2str, &rp->max) < 0) {
154                                 sprintf(errmsg, "error parsing string %s into an integer", n2str);
155                                 free(tmpstr);
156                                 free(ranges);
157                                 return -1;
158                         }
159                 }
160
161                 /*
162                  * Process the 'mult' field - if one was not present 
163                  * (n1:n2 format), or the field was zero length (n1:n2: format)
164                  * then set the mult field to defmult - otherwise pass then
165                  * mult field to the parse function.
166                  */
167
168                 if (multstr != NULL && (int)strlen(multstr) > 0) {
169                         if ((*parse_func)(multstr, &rp->mult) < 0) {
170                                 sprintf(errmsg, "error parsing string %s into an integer", multstr);
171                                 free(tmpstr);
172                                 free(ranges);
173                                 return -1;
174                         }
175                 }
176
177                 rp++;
178                 tok = strtok(NULL, ",");
179         }
180
181         free(tmpstr);
182
183         if (rangeptr != NULL) {
184                 *rangeptr = (char *)ranges;
185         } else {
186                 free(ranges);           /* just running in parse mode */
187         }
188
189         return (rp - ranges);
190 }
191
192 /*
193  * The default integer-parsing function
194  */
195
196 static int
197 str_to_int(str, ip)
198 char    *str;
199 int     *ip;
200 {
201         char    c;
202
203         if (sscanf(str, "%i%c", ip, &c) != 1) {
204                 return -1;
205         } else {
206                 return 0;
207         }
208 }
209
210 /*
211  * Three simple functions to return the min, max, and mult values for a given
212  * range.  It is assumed that rbuf is a range buffer set up by parse_ranges(),
213  * and that r is a valid range within that buffer.
214  */
215
216 int
217 range_min(rbuf, r)
218 char    *rbuf;
219 int     r;
220 {
221         return ((struct range *)rbuf)[r].min;
222 }
223
224 int
225 range_max(rbuf, r)
226 char    *rbuf;
227 int     r;
228 {
229         return ((struct range *)rbuf)[r].max;
230 }
231
232 int
233 range_mult(rbuf, r)
234 char    *rbuf;
235 int     r;
236 {
237         return ((struct range *)rbuf)[r].mult;
238 }
239
240 /*****************************************************************************
241  * random_range(int start, int end, int mult, char **errp)
242  *
243  * Returns a psuedo-random number which is >= 'start', <= 'end', and a multiple
244  * of 'mult'.  Start and end may be any valid integer, but mult must be an
245  * integer > 0.  errp is a char ** which will be set to point to a static
246  * error message buffer if it is not NULL, and an error occurs.
247  *
248  * The errp is the only way to check if the routine fails - currently the only
249  * failure conditions are:
250  *
251  *              mult < 1
252  *              no numbers in the start-end range that are a multiple of 'mult'
253  *
254  * If random_range_fails, and errp is a valid pointer, it will point to an
255  * internal error buffer.  If errp is a vaild pointer, and random_range
256  * is successful, errp will be set to NULL.
257  *
258  * Note - if mult is 1 (the most common case), there are error conditions
259  * possible, and errp need not be used.
260  *
261  * Note:    Uses lrand48(), assuming that set_random_seed() uses srand48() when
262  *          setting the seed.
263  *****************************************************************************/
264
265 long
266 random_range(min, max, mult, errp)
267 int     min;
268 int     max;
269 int     mult;
270 char    **errp;
271 {
272         int             r, nmults, orig_min, orig_max, orig_mult, tmp;
273         extern long     lrand48();
274         static char     errbuf[128];
275
276         /*
277          * Sanity check
278          */
279
280         if (mult < 1) {
281                 if (errp != NULL) {
282                         sprintf(errbuf, "mult arg must be greater than 0");
283                         *errp = errbuf;
284                 }
285                 return -1;
286         }
287
288         /*
289          * Save original parameter values for use in error message
290          */
291
292         orig_min = min;
293         orig_max = max;
294         orig_mult = mult;
295
296         /*
297          * switch min/max if max < min
298          */
299
300         if (max < min) {
301                 tmp = max;
302                 max = min;
303                 min = tmp;
304         }
305
306         /*
307          * select the random number
308          */
309
310         if ((r = min % mult))     /* bump to the next higher 'mult' multiple */
311                 min += mult - r;
312
313         if ((r = max % mult))     /* reduce to the next lower 'mult' multiple */
314                 max -= r;
315
316         if (min > max) {         /* no 'mult' multiples between min & max */
317                 if (errp != NULL) {
318                         sprintf(errbuf, "no numbers in the range %d:%d that are a multiple of %d", orig_min, orig_max, orig_mult);
319                         *errp = errbuf;
320                 }
321                 return -1;
322         }
323
324         if (errp != NULL) {
325                 *errp = NULL;
326         }
327
328         nmults = ((max - min) / mult) + 1;
329         return (min + ((lrand48() % nmults) * mult));
330 }
331
332 /*
333  * Just like random_range, but all values are longs.
334  */
335 long
336 random_rangel(min, max, mult, errp)
337 long    min;
338 long    max;
339 long    mult;
340 char    **errp;
341 {
342         long            r, nmults, orig_min, orig_max, orig_mult, tmp;
343         extern long     lrand48();
344         static char     errbuf[128];
345
346         /*
347          * Sanity check
348          */
349
350         if (mult < 1) {
351                 if (errp != NULL) {
352                         sprintf(errbuf, "mult arg must be greater than 0");
353                         *errp = errbuf;
354                 }
355                 return -1;
356         }
357
358         /*
359          * Save original parameter values for use in error message
360          */
361
362         orig_min = min;
363         orig_max = max;
364         orig_mult = mult;
365
366         /*
367          * switch min/max if max < min
368          */
369
370         if (max < min) {
371                 tmp = max;
372                 max = min;
373                 min = tmp;
374         }
375
376         /*
377          * select the random number
378          */
379
380         if ((r = min % mult))     /* bump to the next higher 'mult' multiple */
381                 min += mult - r;
382
383         if ((r = max % mult))     /* reduce to the next lower 'mult' multiple */
384                 max -= r;
385
386         if (min > max) {         /* no 'mult' multiples between min & max */
387                 if (errp != NULL) {
388                     sprintf(errbuf,
389                         "no numbers in the range %ld:%ld that are a multiple of %ld",
390                         orig_min, orig_max, orig_mult);
391                     *errp = errbuf;
392                 }
393                 return -1;
394         }
395
396         if (errp != NULL) {
397                 *errp = NULL;
398         }
399
400         nmults = ((max - min) / mult) + 1;
401 #if (_MIPS_SZLONG == 64)
402         /*
403          * If max is less than 2gb, then the value can fit in 32 bits
404          * and the standard lrand48() routine can be used.
405          */
406         if ( max <= (long)2147483647 ) {
407             return (long) (min + (((long)lrand48() % nmults) * mult));
408         } else {
409             /*
410              * max is greater than 2gb - meeds more than 32 bits.
411              * Since lrand48 only will get a number up to 32bits.
412              */
413             long randnum;
414             randnum=divider(min, max, 0, -1);
415             return (long) (min + ((randnum % nmults) * mult));
416         }
417
418 #else
419         return (min + ((lrand48() % nmults) * mult));
420 #endif
421 }
422
423 /*
424  *  Attempts to be just like random_range, but everything is long long (64 bit)
425  */
426 long long
427 random_rangell(min, max, mult, errp)
428 long long       min;
429 long long       max;
430 long long       mult;
431 char            **errp;
432 {
433         long long       r, nmults, orig_min, orig_max, orig_mult, tmp;
434         long long       randnum;
435         extern long     lrand48();
436         static char     errbuf[128];
437
438         /*
439          * Sanity check
440          */
441
442         if (mult < 1) {
443                 if (errp != NULL) {
444                         sprintf(errbuf, "mult arg must be greater than 0");
445                         *errp = errbuf;
446                 }
447                 return -1;
448         }
449
450         /*
451          * Save original parameter values for use in error message
452          */
453
454         orig_min = min;
455         orig_max = max;
456         orig_mult = mult;
457
458         /*
459          * switch min/max if max < min
460          */
461
462         if (max < min) {
463                 tmp = max;
464                 max = min;
465                 min = tmp;
466         }
467
468         /*
469          * select the random number
470          */
471
472         if ((r = min % mult))     /* bump to the next higher 'mult' multiple */
473                 min += mult - r;
474
475         if ((r = max % mult))     /* reduce to the next lower 'mult' multiple */
476                 max -= r;
477
478         if (min > max) {         /* no 'mult' multiples between min & max */
479                 if (errp != NULL) {
480                     sprintf(errbuf,
481                         "no numbers in the range %lld:%lld that are a multiple of %lld",
482                         orig_min, orig_max, orig_mult);
483                     *errp = errbuf;
484                 }
485                 return -1;
486         }
487
488         if (errp != NULL) {
489                 *errp = NULL;
490         }
491
492         nmults = ((max - min) / mult) + 1;
493         /*
494          * If max is less than 2gb, then the value can fit in 32 bits
495          * and the standard lrand48() routine can be used.
496          */
497         if ( max <= (long)2147483647 ) {  
498             return (long long) (min + (((long long)lrand48() % nmults) * mult));
499         } else {
500             /*
501              * max is greater than 2gb - meeds more than 32 bits.
502              * Since lrand48 only will get a number up to 32bits.
503              */
504             randnum=divider(min, max, 0, -1);
505             return (long long) (min + ((randnum % nmults) * mult));
506         }
507
508 }
509
510 /*
511  * This functional will recusively call itself to return a random
512  * number min and max.   It was designed to work the 64bit numbers
513  * even when compiled as 32 bit process.
514  * algorithm:  to use the official lrand48() routine - limited to 32 bits.
515  *   find the difference between min and max (max-min).
516  *   if the difference is 2g or less, use the random number gotton from lrand48().
517  *   Determine the midway point between min and max.
518  *   if the midway point is less than 2g from min or max,
519  *      randomly add the random number gotton from lrand48() to
520  *      either min or the midpoint.
521  *   Otherwise, call outself with min and max being min and midway value or
522  *   midway value and max.  This will reduce the range in half.
523  */
524 static long long
525 divider(long long min, long long max, long long cnt, long long rand)
526 {
527     long long med, half, diff;
528
529     /*
530      * prevent run away code.  We are dividing by two each count.
531      * if we get to a count of more than 32, we should have gotten
532      * to 2gb.
533      */
534     if ( cnt > 32 )
535        return -1;
536
537     /*
538      * Only get a random number the first time.
539      */
540     if ( cnt == 0 || rand < -1 ) { 
541         rand = (long long)lrand48();  /* 32 bit random number */
542     }
543
544     diff = max - min;
545
546     if ( diff <= 2147483647 )
547         return min + rand;
548
549     half = diff/(long long)2;   /* half the distance between min and max */
550     med = min + half;           /* med way point between min and max */
551
552 #if DEBUG
553 printf("divider: min=%lld, max=%lld, cnt=%lld, rand=%lld\n", min, max, cnt, rand);
554 printf("   diff = %lld, half = %lld,   med = %lld\n", diff, half, med);
555 #endif
556
557     if ( half <= 2147483647 ) {
558         /*
559          * If half is smaller than 2gb, we can use the random number
560          * to pick the number within the min to med or med to max
561          * if the cnt bit of rand is zero or one, respectively.
562          */
563         if ( rand & (1<<cnt) )
564             return med + rand;
565         else
566             return min + rand;
567     } else {
568         /*
569          * recursively call ourself to reduce the value to the bottom half
570          * or top half (bit cnt is set).
571          */
572         if ( rand & (1<<cnt) ) {
573             return divider(med, max, cnt+1, rand);
574         } else {
575             return divider(min, med, cnt+1, rand);
576         }
577         
578     }
579
580 }
581
582
583 /*****************************************************************************
584  * random_range_seed(s)
585  *
586  * Sets the random seed to s.  Uses srand48(), assuming that lrand48() will
587  * be used in random_range().
588  *****************************************************************************/
589
590 void
591 random_range_seed(s)
592 long    s;
593 {
594     extern void srand48();
595
596     srand48(s);
597 }
598
599 /****************************************************************************
600  * random_bit(mask)
601  *
602  * This function randomly returns a single bit from the bits
603  * set in mask.  If mask is zero, zero is returned.
604  *
605  ****************************************************************************/
606 long
607 random_bit(long mask)
608 {
609     int nbits = 0;      /* number of set bits in mask */
610     long bit;           /* used to count bits and num of set bits choosen */
611     int nshift;         /* used to count bit shifts */
612
613     if ( mask == 0 )
614         return 0;
615
616     /*
617      * get the number of bits set in mask
618      */
619         bit=1L;
620         for ( nshift=0; nshift<sizeof(long)*8; nshift++) {
621                 if ( mask & bit )
622                         nbits++;
623                 bit=bit<<1;
624         }
625
626     /*
627      * randomly choose a bit.
628      */
629     bit=random_range(1, nbits, 1, NULL);
630
631     /*
632      * shift bits until you determine which bit was randomly choosen.
633      * nshift will hold the number of shifts to make.
634      */
635
636     nshift=0;
637     while (bit) {
638         /* check if the current one's bit is set */
639         if ( mask & 1L ) {
640             bit--;
641         }
642         mask = mask >> 1;
643         nshift++;
644     }
645
646     return 01L << (nshift-1);
647
648 }
649
650
651 #if RANDOM_BIT_UNITTEST
652 /*
653  *  The following is a unit test main function for random_bit().
654  */
655 main(argc, argv)
656 int argc;
657 char **argv;
658 {
659     int ind;
660     int cnt, iter;
661     long mask, ret;
662
663     printf("test for first and last bit set\n");
664     mask=1L;
665     ret=random_bit(mask);
666     printf("random_bit(%#o) returned %#o\n", mask, ret);
667
668     mask=1L<<(sizeof(long)*8-1);
669     ret=random_bit(mask);
670     printf("random_bit(%#o) returned %#o\n", mask, ret);
671
672     if ( argc >= 3 ) {
673         iter=atoi(argv[1]);
674         for (ind=2; ind<argc; ind++) {
675             printf("Calling random_bit %d times for mask %#o\n", iter, mask);
676             sscanf(argv[ind], "%i", &mask);
677             for (cnt=0; cnt<iter; cnt++) {
678                 ret=random_bit(mask);
679                 printf("random_bit(%#o) returned %#o\n", mask, ret);
680             }
681         }
682     }
683     exit(0);
684 }
685
686 #endif /* end if RANDOM_BIT_UNITTEST */
687
688
689 #if UNIT_TEST
690 /*
691  *  The following is a unit test main function for random_range*().
692  */
693
694 #define PARTNUM 10      /* used to determine even distribution of random numbers */
695 #define MEG  1024*1024*1024
696 #define GIG 1073741824
697 int
698 main(argc, argv)
699 int argc;
700 char **argv;
701 {
702     int ind;
703     int cnt, iter=10;
704     int imin=0, imult=1, itmin, itmax=0;
705     int imax=1048576;
706
707     long lret, lmin=0, lmult=1, ltmin, ltmax=0; 
708 #if (_MIPS_SZLONG == 64)
709     long lmax=6*(long)GIG;      /* higher than 32 bits */
710 #else
711     long lmax=1048576;
712 #endif
713     long long llret, llmin=0, llmult=1, lltmin, lltmax=0;
714     long long llmax=(long long)80*(long long)GIG;
715
716     long part;
717     long long lpart;
718     long cntarr[PARTNUM];
719     long valbound[PARTNUM];
720     long long lvalbound[PARTNUM];
721
722     for (ind=0; ind<PARTNUM; ind++ )
723         cntarr[ind]=0;
724     
725     if ( argc < 2 ) {
726         printf("Usage: %s func [iterations] \n", argv[0]);
727         printf("func can be random_range, random_rangel, random_rangell\n");
728         exit(1);
729     }
730
731     if ( argc >= 3 ) {
732         if ( sscanf(argv[2], "%i", &iter) != 1 ) {
733             printf("Usage: %s [func iterations] \n", argv[0]);
734             printf("argv[2] is not a number\n");
735             exit(1);
736         }
737     }
738
739
740     /*
741      * random_rangel ()
742      */
743     if ( strcmp(argv[1], "random_rangel") == 0 ) {
744         ltmin=lmax;
745         part = lmax/PARTNUM;
746         for(ind=0; ind<PARTNUM; ind++) {
747             valbound[ind]=part*ind;
748         }
749
750         for(cnt=0; cnt<iter; cnt++) {
751             lret=random_rangel(lmin, lmax, lmult, NULL);
752             if ( iter < 100 )
753                 printf("%ld\n", lret);
754             if ( lret < ltmin )
755                 ltmin = lret;
756             if ( lret > ltmax )
757                 ltmax = lret;
758             for(ind=0; ind<PARTNUM-1; ind++) {
759                 if ( valbound[ind]  < lret && lret <= valbound[ind+1] ) {
760                     cntarr[ind]++;
761                     break;
762                 }
763             }
764             if ( lret > valbound[PARTNUM-1] ) {
765                 cntarr[PARTNUM-1]++;
766             }
767         }
768         for(ind=0; ind<PARTNUM-1; ind++) {
769             printf("%2d %-13ld to  %-13ld   %5ld %4.4f\n", ind+1,
770                 valbound[ind], valbound[ind+1], cntarr[ind],
771                 (float)(cntarr[ind]/(float)iter));
772         }
773         printf("%2d %-13ld to  %-13ld   %5ld %4.4f\n", PARTNUM, 
774             valbound[PARTNUM-1], lmax, cntarr[PARTNUM-1],
775             (float)(cntarr[PARTNUM-1]/(float)iter));
776         printf("  min=%ld,  max=%ld\n", ltmin, ltmax);
777
778     } else if ( strcmp(argv[1], "random_rangell") == 0 ) {
779        /*
780         * random_rangell() unit test
781         */
782          lltmin=llmax;
783         lpart = llmax/PARTNUM;
784         for(ind=0; ind<PARTNUM; ind++) {
785             lvalbound[ind]=(long long)(lpart*ind);
786         }
787
788         for(cnt=0; cnt<iter; cnt++) {
789             llret=random_rangell(llmin, llmax, llmult, NULL);
790             if ( iter < 100 )
791                 printf("random_rangell returned %lld\n", llret);
792             if ( llret < lltmin )
793                 lltmin = llret;
794             if ( llret > lltmax )
795                 lltmax = llret;
796
797             for(ind=0; ind<PARTNUM-1; ind++) {
798                 if ( lvalbound[ind]  < llret && llret <= lvalbound[ind+1] ) {
799                     cntarr[ind]++;
800                     break;
801                 }
802             }
803             if ( llret > lvalbound[PARTNUM-1] ) {
804                 cntarr[PARTNUM-1]++;
805             }
806         }
807         for(ind=0; ind<PARTNUM-1; ind++) {
808             printf("%2d %-13lld to  %-13lld   %5ld %4.4f\n", ind+1,
809                 lvalbound[ind], lvalbound[ind+1], cntarr[ind],
810                 (float)(cntarr[ind]/(float)iter));
811         }
812         printf("%2d %-13lld to  %-13lld   %5ld %4.4f\n", PARTNUM,
813             lvalbound[PARTNUM-1], llmax, cntarr[PARTNUM-1],
814             (float)(cntarr[PARTNUM-1]/(float)iter));
815         printf("  min=%lld,  max=%lld\n", lltmin, lltmax);
816
817     } else {
818         /*
819          * random_range() unit test
820          */
821         itmin=imax;
822         part = imax/PARTNUM;
823         for(ind=0; ind<PARTNUM; ind++) {
824             valbound[ind]=part*ind;
825         }
826
827         for(cnt=0; cnt<iter; cnt++) {
828             lret=random_range(imin, imax, imult, NULL);
829             if ( iter < 100 )
830                 printf("%ld\n", lret);
831             if ( lret < itmin )
832                 itmin = lret;
833             if ( lret > itmax )
834                 itmax = lret;
835
836             for(ind=0; ind<PARTNUM-1; ind++) {
837                 if ( valbound[ind]  < lret && lret <= valbound[ind+1] ) {
838                     cntarr[ind]++;
839                     break;
840                 }
841             }
842             if ( lret > valbound[PARTNUM-1] ) {
843                 cntarr[PARTNUM-1]++;
844             }
845         }
846         for(ind=0; ind<PARTNUM-1; ind++) {
847             printf("%2d %-13ld to  %-13ld   %5ld %4.4f\n", ind+1,
848                 valbound[ind], valbound[ind+1], cntarr[ind],
849                 (float)(cntarr[ind]/(float)iter));
850         }
851         printf("%2d %-13ld to  %-13ld   %5ld %4.4f\n", PARTNUM, 
852             valbound[PARTNUM-1], (long)imax, cntarr[PARTNUM-1],
853             (float)(cntarr[PARTNUM-1]/(float)iter));
854         printf("  min=%d,  max=%d\n", itmin, itmax);
855
856     }
857
858     exit(0);
859 }
860
861 #endif