// Digit sequence level random number generator.
// General includes.
#include "cl_sysdep.h"
// Specification.
#include "cl_random_impl.h"
// Implementation.
#include "cln/random.h"
#include "cl_DS.h"
#include "cl_low.h"
namespace cln {
void testrandom_UDS (random_state& randomstate, uintD* MSDptr, uintC len)
{
// Idea from Torbjörn Granlund, see his "random2.c" file in gmp 2.0.
var uintD* ptr = MSDptr mspop len;
DS_clear_loop(MSDptr,len,ptr);
var uintL bit_pos = 0;
var uint32 ran = 0;
var uintC ran_bits = 0;
while (bit_pos < intDsize*(uintL)len)
{ if (ran_bits < log2_intDsize+1)
{ ran = random32(randomstate); ran_bits = 32; }
var uintL n_bits = (ran >> 1) % intDsize + 1; // number of bits
if (ran & 1)
{ // put in a bit string of n_bits bits at position bit_pos.
if (bit_pos + n_bits > intDsize*(uintL)len)
{ n_bits = intDsize*(uintL)len - bit_pos; }
if (bit_pos / intDsize == (bit_pos + n_bits - 1) / intDsize)
{ // need to modify one digit
lspref(ptr,bit_pos/intDsize) |= (((uintD)1 << n_bits) - 1) << (bit_pos%intDsize);
}
else
{ // need to modify two adjacent digits
lspref(ptr,bit_pos/intDsize) |= ((uintD)(-1) << (bit_pos%intDsize));
lspref(ptr,bit_pos/intDsize+1) |= (((uintD)1 << ((bit_pos+n_bits)%intDsize)) - 1);
}
}
bit_pos = bit_pos + n_bits;
ran = ran >> (log2_intDsize+1); ran_bits -= log2_intDsize+1;
}
}
} // namespace cln
syntax highlighted by Code2HTML, v. 0.9.1