]> www.ginac.de Git - cln.git/blob - src/base/digitseq/cl_DS_trandom.cc
* All Files have been modified for inclusion of namespace cln;
[cln.git] / src / base / digitseq / cl_DS_trandom.cc
1 // Digit sequence level random number generator.
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 // Specification.
7 #include "cl_random_impl.h"
8
9
10 // Implementation.
11
12 #include "cln/random.h"
13 #include "cl_DS.h"
14 #include "cl_low.h"
15
16 namespace cln {
17
18 void testrandom_UDS (random_state& randomstate, uintD* MSDptr, uintC len)
19 {
20   // Idea from Torbjörn Granlund, see his "random2.c" file in gmp 2.0.
21   var uintD* ptr = MSDptr mspop len;
22   DS_clear_loop(MSDptr,len,ptr);
23   var uintL bit_pos = 0;
24   var uint32 ran = 0;
25   var uintC ran_bits = 0;
26   while (bit_pos < intDsize*(uintL)len)
27     { if (ran_bits < log2_intDsize+1)
28         { ran = random32(randomstate); ran_bits = 32; }
29       var uintL n_bits = (ran >> 1) % intDsize + 1; // number of bits
30       if (ran & 1)
31         { // put in a bit string of n_bits bits at position bit_pos.
32           if (bit_pos + n_bits > intDsize*(uintL)len)
33             { n_bits = intDsize*(uintL)len - bit_pos; }
34           if (bit_pos / intDsize == (bit_pos + n_bits - 1) / intDsize)
35             { // need to modify one digit
36               lspref(ptr,bit_pos/intDsize) |= (((uintD)1 << n_bits) - 1) << (bit_pos%intDsize);
37             }
38             else
39             { // need to modify two adjacent digits
40               lspref(ptr,bit_pos/intDsize) |= ((uintD)(-1) << (bit_pos%intDsize));
41               lspref(ptr,bit_pos/intDsize+1) |= (((uintD)1 << ((bit_pos+n_bits)%intDsize)) - 1);
42             }
43         }
44       bit_pos = bit_pos + n_bits;
45       ran = ran >> (log2_intDsize+1); ran_bits -= log2_intDsize+1;
46     }
47 }
48
49 }  // namespace cln