11/*
2- ** $Id: lmathlib.c,v 1.127 2018/03/22 19:54:49 roberto Exp roberto $
2+ ** $Id: lmathlib.c,v 1.128 2018/03/26 19:48:46 roberto Exp $
33** Standard mathematical library
44** See Copyright Notice in lua.h
55*/
@@ -247,7 +247,7 @@ static int math_type (lua_State *L) {
247247
248248/*
249249** {==================================================================
250- ** Pseudo-Random Number Generator based on 'xorshift128 +'.
250+ ** Pseudo-Random Number Generator based on 'xoroshiro128 +'.
251251** ===================================================================
252252*/
253253
@@ -270,34 +270,45 @@ static int math_type (lua_State *L) {
270270/* a 64-bit value */
271271typedef unsigned long long I ;
272272
273- static I xorshift128plus (I * state ) {
274- I x = state [0 ];
275- I y = state [1 ];
276- state [0 ] = y ;
277- x ^= x << 23 ;
278- state [1 ] = (x ^ (x >> 18 )) ^ (y ^ (y >> 5 ));
279- return state [1 ] + y ;
273+
274+ /* rotate left 'x' by 'n' bits */
275+ static I rotl (I x , int n ) {
276+ return (x << n ) | (x >> (64 - n ));
277+ }
278+
279+ static I nextrand (I * state ) {
280+ I s0 = state [0 ];
281+ I s1 = state [1 ];
282+ I res = s0 + s1 ;
283+ res = rotl (res , 41 ); /* extra step to change place of lower bits */
284+ s1 = s1 ^ s0 ;
285+ state [0 ] = rotl (s0 , 55 ) ^ (s1 ^ (s1 << 14 ));
286+ state [1 ] = rotl (s1 , 36 );
287+ return res ;
280288}
281289
290+
282291/* must take care to not shift stuff by more than 63 slots */
283292
284- #define shiftI (64 - FIGS) /* leave FIGS bits */
285- #define shiftF (l_mathop(0.5) / (1LLU << (FIGS - 1))) /* 2^(-FIG) */
286293
287294/*
288295** Convert bits from a random integer into a float in the
289296** interval [0,1).
290297*/
298+ #define maskFIG (~(~1LLU << (FIGS - 1))) /* use FIGS bits */
299+ #define shiftFIG (l_mathop(0.5) / (1LLU << (FIGS - 1))) /* 2^(-FIGS) */
300+
291301static lua_Number I2d (I x ) {
292- return (lua_Number )(x >> shiftI ) * shiftF ;
302+ return (lua_Number )(x & maskFIG ) * shiftFIG ;
293303}
294304
295- /* convert an 'I' to a lua_Unsigned (using higher bits) */
296- #define I2UInt (x ) ((lua_Unsigned)((x) >> (64 - LUA_UNSIGNEDBITS) ))
305+ /* convert an 'I' to a lua_Unsigned */
306+ #define I2UInt (x ) ((lua_Unsigned)(x ))
297307
298- /* convert a lua_Integer to an 'I' */
308+ /* convert a lua_Unsigned to an 'I' */
299309#define Int2I (x ) ((I)(x))
300310
311+
301312#else /* no long long }{ */
302313
303314/*
@@ -330,14 +341,10 @@ static I packI (lu_int32 h, lu_int32 l) {
330341
331342/* i ^ (i << n) */
332343static I Ixorshl (I i , int n ) {
344+ lua_assert (n > 0 && n < 32 );
333345 return packI (i .h ^ ((i .h << n ) | (i .l >> (32 - n ))), i .l ^ (i .l << n ));
334346}
335347
336- /* i ^ (i >> n) */
337- static I Ixorshr (I i , int n ) {
338- return packI (i .h ^ (i .h >> n ), i .l ^ ((i .l >> n ) | (i .h << (32 - n ))));
339- }
340-
341348static I Ixor (I i1 , I i2 ) {
342349 return packI (i1 .h ^ i2 .h , i1 .l ^ i2 .l );
343350}
@@ -349,18 +356,29 @@ static I Iadd (I i1, I i2) {
349356 return result ;
350357}
351358
359+ /*
360+ ** Rotate left. As all offsets here are larger than 32, do a rotate right
361+ ** of 64 - offset.
362+ */
363+ static I Irotli (I i , int n ) {
364+ n = 64 - n ;
365+ lua_assert (n > 0 && n < 32 );
366+ return packI ((i .h >> n ) | (i .l << (32 - n )),
367+ (i .h << (32 - n )) | (i .l >> n ));
368+ }
352369
353370/*
354- ** implementation of 'xorshift128 +' algorithm on 'I' values
371+ ** implementation of 'xoroshiro128 +' algorithm on 'I' values
355372*/
356- static I xorshift128plus (I * state ) {
357- I x = state [0 ];
358- I y = state [1 ];
359- state [0 ] = y ;
360- x = Ixorshl (x , 23 ); /* x ^= x << 23; */
361- /* state[1] = (x ^ (x >> 18)) ^ (y ^ (y >> 5)); */
362- state [1 ] = Ixor (Ixorshr (x , 18 ), Ixorshr (y , 5 ));
363- return Iadd (state [1 ], y ); /* return state[1] + y; */
373+ static I nextrand (I * state ) {
374+ I s0 = state [0 ];
375+ I s1 = state [1 ];
376+ I res = Iadd (s0 , s1 );
377+ res = Irotli (res , 41 );
378+ s1 = Ixor (s1 , s0 );
379+ state [0 ] = Ixor (Irotli (s0 , 55 ), Ixorshl (s1 , 14 ));
380+ state [1 ] = Irotli (s1 , 36 );
381+ return res ;
364382}
365383
366384
@@ -373,45 +391,39 @@ static I xorshift128plus (I *state) {
373391
374392#if FIGS <= 32
375393
376- #define maskLOW 0 /* do not need bits from lower half */
377- #define maskHI (~(~(lu_int32)0 >> (FIGS - 1) >> 1)) /* use FIGS bits */
378- #define shiftHI 1 /* no shift */
379- #define shiftF (1 / l_mathop(4294967296.0)) /* 2^(-32) */
394+ #define maskHI 0 /* do not need bits from higher half */
395+ #define maskLOW (~(~UONE << (FIGS - 1))) /* use FIGS bits */
396+ #define shiftFIG (l_mathop(0.5) / (UONE << (FIGS - 1))) /* 2^(-FIGS) */
380397
381398#else /* 32 < FIGS <= 64 */
382399
383400/* must take care to not shift stuff by more than 31 slots */
384401
385- /* use FIGS - 32 bits from lower half */
386- #define maskLOW (~(~(lu_int32)0 >> (FIGS - 33) >> 1))
387-
388- /* use all bits from higher half */
389- #define maskHI (~(lu_int32)0)
402+ /* use FIGS - 32 bits from higher half */
403+ #define maskHI (~(~UONE << (FIGS - 33)))
390404
391- #define shiftHI l_mathop(4294967296.0) /* 2^32 */
405+ /* use all bits from lower half */
406+ #define maskLOW (~(lu_int32)0)
392407
393- /* 2^(-64 ) */
394- #define shiftF ((lua_Number)(1 / (shiftHI * shiftHI )))
408+ /* 2^(-FIGS) == (1 / 2^33) / 2^(FIGS-33 ) */
409+ #define shiftFIG ((lua_Number)(1.0 / 8589934592.0) / (UONE << (FIGS - 33 )))
395410
396411#endif
397412
413+ #define twoto32 l_mathop(4294967296.0) /* 2^32 */
414+
398415static lua_Number I2d (I x ) {
399416 lua_Number h = (lua_Number )(x .h & maskHI );
400417 lua_Number l = (lua_Number )(x .l & maskLOW );
401- return (h * shiftHI + l ) * shiftF ;
418+ return (h * twoto32 + l ) * shiftFIG ;
402419}
403420
421+
404422static lua_Unsigned I2UInt (I x ) {
405- #if (LUA_MAXINTEGER >> 30 ) <= 1
406- /* at most 32 bits; use only high bits */
407- return ((lua_Unsigned )x .h );
408- #else
409- /* at least 33 bits */
410- return ((lua_Unsigned )x .h << (LUA_UNSIGNEDBITS - 32 )) |
411- (lua_Unsigned )x .l >> (64 - LUA_UNSIGNEDBITS );
412- #endif
423+ return ((lua_Unsigned )x .h << 31 << 1 ) | (lua_Unsigned )x .l ;
413424}
414425
426+
415427static I Int2I (lua_Unsigned n ) {
416428 return packI ((lu_int32 )(n >> 31 >> 1 ), (lu_int32 )n & ~(lu_int32 )0 );
417429}
@@ -427,55 +439,44 @@ typedef struct {
427439} RanState ;
428440
429441
430- /*
431- ** Return the higher bit set in 'x' (first bit is 1).
432- */
433- static int higherbit (lua_Unsigned x ) {
434- /* table of higher bits from 0 to 255 */
435- static const unsigned char hb [256 ] = {
436- 0 ,1 ,2 ,2 ,3 ,3 ,3 ,3 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,
437- 6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,
438- 7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,
439- 7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,
440- 8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,
441- 8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,
442- 8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,
443- 8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8
444- };
445- int l = 0 ;
446- while (x >= 256 ) { l += 8 ; x >>= 8 ; }
447- return l + hb [x ];
448- }
449-
450-
451442/*
452443** Project the random integer 'ran' into the interval [0, n].
453- ** To get a uniform projection into [0,n], we first compute 'shf', the
454- ** largest number that we can right-shift 'ran' and still get numbers
455- ** as larger as 'n'. We then shift 'ran'; if the result is inside [0, n],
456- ** we are done. Otherwise, we try with another 'ran' until we have a
457- ** result inside the interval. (We use right shifts to avoid the lowest
458- ** bits of 'ran', which has poorer distributions.)
444+ ** Because 'ran' has 2^B possible values, the projection can only be
445+ ** uniform when the size of the interval is a power of 2 (exact
446+ ** division). To get a uniform projection into [0, n], we first compute
447+ ** 'lim', the smallest Mersenne number not smaller than 'n'. We then
448+ ** project 'ran' into the interval [0, lim]. If the result is inside
449+ ** [0, n], we are done. Otherwise, we try with another 'ran' until we
450+ ** have a result inside the interval.
459451*/
460452static lua_Unsigned project (lua_Unsigned ran , lua_Unsigned n ,
461453 RanState * state ) {
462- if (n == 0 ) return 0 ; /* special case for the unit set */
463- else {
464- int shf = LUA_UNSIGNEDBITS - higherbit (n );
465- lua_assert (~(lua_Unsigned )0 >> shf >= n && /* not larger */
466- ~(lua_Unsigned )0 >> shf >> 1 < n ); /* largest */
467- while ((ran >>= shf ) > n )
468- ran = I2UInt (xorshift128plus (state -> s ));
469- return ran ;
454+ lua_Unsigned lim = n ;
455+ if ((lim & (lim + 1 )) > 0 ) { /* 'lim + 1' is not a power of 2? */
456+ /* compute the smallest (2^b - 1) not smaller than 'n' */
457+ lim |= (lim >> 1 );
458+ lim |= (lim >> 2 );
459+ lim |= (lim >> 4 );
460+ lim |= (lim >> 8 );
461+ lim |= (lim >> 16 );
462+ #if (LUA_MAXINTEGER >> 30 >> 2 ) > 0
463+ lim |= (lim >> 32 ); /* integer type has more than 32 bits */
464+ #endif
470465 }
466+ lua_assert ((lim & (lim + 1 )) == 0 /* 'lim + 1' is a power of 2 */
467+ && lim >= n /* not smaller than 'n' */
468+ && (lim == 0 || (lim >> 1 ) < n )); /* it is the smallest one */
469+ while ((ran &= lim ) > n )
470+ ran = I2UInt (nextrand (state -> s ));
471+ return ran ;
471472}
472473
473474
474475static int math_random (lua_State * L ) {
475476 lua_Integer low , up ;
476477 lua_Unsigned p ;
477478 RanState * state = (RanState * )lua_touserdata (L , lua_upvalueindex (1 ));
478- I rv = xorshift128plus (state -> s ); /* next pseudo-random value */
479+ I rv = nextrand (state -> s ); /* next pseudo-random value */
479480 switch (lua_gettop (L )) { /* check number of arguments */
480481 case 0 : { /* no arguments */
481482 lua_pushnumber (L , I2d (rv )); /* float between 0 and 1 */
@@ -511,7 +512,7 @@ static void setseed (I *state, lua_Unsigned n) {
511512 state [0 ] = Int2I (n );
512513 state [1 ] = Int2I (0xff ); /* avoid a zero state */
513514 for (i = 0 ; i < 16 ; i ++ )
514- xorshift128plus (state ); /* discard initial values to "spread" seed */
515+ nextrand (state ); /* discard initial values to "spread" seed */
515516}
516517
517518
0 commit comments