[project @ 1998-11-26 09:17:22 by sof]
[ghc-hetmet.git] / ghc / runtime / gmp / mpz_random2.c
1 /* mpz_random2 -- Generate a positive random MP_INT of specified size, with
2    long runs of consecutive ones and zeros in the binary representation.
3    Meant for testing of other MP routines.
4
5 Copyright (C) 1991, 1993 Free Software Foundation, Inc.
6
7 This file is part of the GNU MP Library.
8
9 The GNU MP Library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13
14 The GNU MP Library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with the GNU MP Library; see the file COPYING.  If not, write to
21 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
22
23 #include "gmp.h"
24 #include "gmp-impl.h"
25
26 #if !defined(__GNUC__)
27 #define __inline__ inline
28 #endif
29
30 #if defined (hpux) || defined (__alpha__)
31 /* HPUX lacks random().  DEC Alpha's random() returns a double.  */
32 static __inline__ long
33 random ()
34 {
35   return mrand48 ();
36 }
37 #else
38 long random ();
39 #endif
40
41 void
42 #ifdef __STDC__
43 mpz_random2 (MP_INT *x, mp_size size)
44 #else
45 mpz_random2 (x, size)
46      MP_INT *x;
47      mp_size size;
48 #endif
49 {
50   mp_limb ran, cy_limb;
51   mp_ptr xp;
52   mp_size xsize, abs_size;
53   int n_bits;
54
55   abs_size = ABS (size);
56
57   if (abs_size != 0)
58     {
59       if (x->alloc < abs_size)
60         _mpz_realloc (x, abs_size);
61       xp = x->d;
62
63       xp[0] = 1;
64       for (xsize = 1;; )
65         {
66           ran = random ();
67           n_bits = (ran >> 1) % BITS_PER_MP_LIMB;
68
69           if (n_bits == 0)
70             {
71               if (xsize == abs_size)
72                 break;
73             }
74           else
75             {
76               /* Would we get a too large result in mpn_lshift?  */
77               if (xsize == abs_size
78                   && (xp[xsize - 1] >> (BITS_PER_MP_LIMB - n_bits)) != 0)
79                 break;
80
81               cy_limb = mpn_lshift (xp, xp, xsize, n_bits);
82               if (cy_limb != 0)
83                 xp[xsize++] = cy_limb;
84
85               if (ran & 1)
86                 xp[0] |= ((mp_limb) 1 << n_bits) - 1;
87             }
88         }
89     }
90
91   x->size = size;
92 }