long ignuin(lua_RNG *o,long low,long high) /* ********************************************************************** GeNerate Uniform INteger Function Generates an integer uniformly distributed between LOW and HIGH. Arguments low --> Low bound (inclusive) on integer value to be generated high --> High bound (inclusive) on integer value to be generated Note If (HIGH-LOW) > maxnum prints error message on * unit and stops the program. ********************************************************************** IGNLGI generates integers between 1 and 2147483648 MAXNUM is 1 less than maximum generable value */ { #define maxnum 2147483647L static unsigned long ignuin,ign,maxnow,range,ranp1; if(!(low > high)) goto S10; fputs(" low > high in ignuin - ABORT",stderr); exit(1); S10: range = high-low; if(!(range > maxnum)) goto S20; fputs(" high - low too large in ignuin - ABORT",stderr); exit(1); S20: if(!(low == high)) goto S30; ignuin = low; return ignuin; S30: /* Number to be generated should be in range 0..RANGE Set MAXNOW so that the number of integers in 0..MAXNOW is an integral multiple of the number in 0..RANGE */ ranp1 = range+1; maxnow = maxnum/ranp1*ranp1; S40: ign = ignlgi(o); if(!(ign <= maxnow)) goto S50; ignuin = low+ign%ranp1; return ignuin; S50: goto S40; #undef maxnum #undef err1 #undef err2 }
/*--------------------------------------------------------------------------*/ double C2F(ignuin)(double *a, double *b) { /* random deviate from Ui[a,b] * it is assumed that : (i) a and b are integers (stored in double) * (ii) b-a+1 <= RngMaxInt[current_gen] * (these verif are done at the calling level) * * We use the classic method with a minor difference : to choose * uniformly an int in [a,b] (ie d=b-a+1 numbers) with a generator * which provides uniformly integers in [0,RngMaxInt] (ie m=RngMaxInt+1 * numbers) we do the Euclidian division : * m = q d + r, r in [0,d-1] * * and accept only numbers l in [0, qd-1], then the output is k = a + (l mod d) * (ie numbers falling in [qd , RngMaxInt] are rejected). * The problem is that RngMaxInt is 2^32-1 for mt and kiss so that RngMaxInt+1 = 0 * with the 32 bits unsigned int arithmetic. So in place of rejected r * numbers we reject r+1 by using RngMaxInt in place of m. The constraint is * then that (b-a+1) <= RngMaxInt and if we doesn't want to deal we each generator * we take (b-a+1) <= Min RngMaxInt = 2147483561 (clcg2) */ // all the generators provided integers in [0, RngMaxInt] : unsigned long RngMaxInt[NbGenInScilab] = { 4294967295ul, // mt 4294967295ul, // kiss 2147483646ul, // clcg4 2147483561ul, // clcg2 2147483647ul, // urand 4294967295ul }; // fsultra int current_gen = ConfigVariable::getCurrentBaseGen(); unsigned long k, d = (unsigned long)((*b - *a) + 1), qd; if (d == 1) { return (*a); } qd = RngMaxInt[current_gen] - RngMaxInt[current_gen] % d; do { k = (unsigned long)ignlgi(); } while (k >= qd); return (*a + (double)(k % d)); }