aboutsummaryrefslogtreecommitdiff
path: root/lmathlib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-05-04 17:01:45 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-05-04 17:01:45 -0300
commit3e7415e846f2f75ed29e27e1211205ea6243e0c7 (patch)
tree6c7fd1371648cd62f4ead5f9f25cb2e46a42b11d /lmathlib.c
parente64e20ac8136b6cf53601127fc5c69310d644eeb (diff)
downloadlua-3e7415e846f2f75ed29e27e1211205ea6243e0c7.tar.gz
lua-3e7415e846f2f75ed29e27e1211205ea6243e0c7.tar.bz2
lua-3e7415e846f2f75ed29e27e1211205ea6243e0c7.zip
reorganization of '#if's for sellecting a type for 'Rand64' +
comments
Diffstat (limited to 'lmathlib.c')
-rw-r--r--lmathlib.c87
1 files changed, 56 insertions, 31 deletions
diff --git a/lmathlib.c b/lmathlib.c
index 3f17890b..16b8a9cc 100644
--- a/lmathlib.c
+++ b/lmathlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lmathlib.c,v 1.130 2018/04/06 15:41:29 roberto Exp roberto $ 2** $Id: lmathlib.c,v 1.131 2018/04/06 17:52:42 roberto Exp roberto $
3** Standard mathematical library 3** Standard mathematical library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -257,27 +257,45 @@ static int math_type (lua_State *L) {
257#endif 257#endif
258 258
259 259
260#if (!defined(LUA_USE_C89) && defined(LLONG_MAX) && !defined(LUA_DEBUG)) \
261 || defined(Rand64) /* { */
262
263/* 260/*
264** Assume long long. 261** LUA_RAND32 forces the use of 32-bit integers in the implementation
262** of the PRN generator (mainly for testing).
265*/ 263*/
264#if !defined(LUA_RAND32) && !defined(Rand64)
265
266/* try to find an integer type with at least 64 bits */
267
268#if (LONG_MAX >> 31 >> 31) >= 1
269
270/* 'long' has at least 64 bits */
271#define Rand64 unsigned long
272
273#elif !defined(LUA_USE_C89) && defined(LLONG_MAX)
274
275/* there is a 'long long' type (which must have at least 64 bits) */
276#define Rand64 unsigned long long
277
278#elif (LUA_MAXINTEGER >> 31 >> 31) >= 1
279
280/* 'lua_Integer' has at least 64 bits */
281#define Rand64 LUA_UNSIGNED
282
283#endif
266 284
267#if !defined(Rand64)
268/* a 64-bit value */
269typedef unsigned long long Rand64;
270#endif 285#endif
271 286
272 287
288#if defined(Rand64) /* { */
289
273/* 290/*
291** Standard implementation, using 64-bit integers.
274** If 'Rand64' has more than 64 bits, the extra bits do not interfere 292** If 'Rand64' has more than 64 bits, the extra bits do not interfere
275** with the 64 initial bits, except in a right shift. Otherwise, we just 293** with the 64 initial bits, except in a right shift. Moreover, the
276** have to make sure we never use them. 294** final result has to discard the extra bits.
277*/ 295*/
278 296
279/* avoid using extra bits when needed */ 297/* avoid using extra bits when needed */
280#define trim64(x) ((x) & 0xffffffffffffffffU) 298#define trim64(x) ((x) & 0xffffffffffffffffu)
281 299
282 300
283/* rotate left 'x' by 'n' bits */ 301/* rotate left 'x' by 'n' bits */
@@ -315,24 +333,23 @@ static lua_Number I2d (Rand64 x) {
315/* convert a 'Rand64' to a 'lua_Unsigned' */ 333/* convert a 'Rand64' to a 'lua_Unsigned' */
316#define I2UInt(x) ((lua_Unsigned)trim64(x)) 334#define I2UInt(x) ((lua_Unsigned)trim64(x))
317 335
318/* convert a 'lua_Unsigned' to an 'Rand64' */ 336/* convert a 'lua_Unsigned' to a 'Rand64' */
319#define Int2I(x) ((Rand64)(x)) 337#define Int2I(x) ((Rand64)(x))
320 338
321 339
322#else /* no long long }{ */ 340#else /* no 'Rand64' }{ */
323
324/*
325** Use two 32-bit integers to represent a 64-bit quantity.
326*/
327 341
328#if LUAI_BITSINT >= 32 342/* get an integer with at least 32 bits */
343#if (INT_MAX >> 30) >= 1
329typedef unsigned int lu_int32; 344typedef unsigned int lu_int32;
330#else 345#else
331typedef unsigned long lu_int32; 346typedef unsigned long lu_int32;
332#endif 347#endif
333 348
334 349
335/* a 64-bit value */ 350/*
351** Use two 32-bit integers to represent a 64-bit quantity.
352*/
336typedef struct Rand64 { 353typedef struct Rand64 {
337 lu_int32 h; /* higher half */ 354 lu_int32 h; /* higher half */
338 lu_int32 l; /* lower half */ 355 lu_int32 l; /* lower half */
@@ -342,17 +359,18 @@ typedef struct Rand64 {
342/* 359/*
343** If 'lu_int32' has more than 32 bits, the extra bits do not interfere 360** If 'lu_int32' has more than 32 bits, the extra bits do not interfere
344** with the 32 initial bits, except in a right shift and comparisons. 361** with the 32 initial bits, except in a right shift and comparisons.
345** Otherwise, we just have to make sure we never use them. 362** Moreover, the final result has to discard the extra bits.
346*/ 363*/
347 364
348/* avoid using extra bits when needed */ 365/* avoid using extra bits when needed */
349#define trim32(x) ((x) & 0xffffffffU) 366#define trim32(x) ((x) & 0xffffffffu)
350 367
351 368
352/* 369/*
353** basic operations on 'Rand64' values 370** basic operations on 'Rand64' values
354*/ 371*/
355 372
373/* build a new Rand64 value */
356static Rand64 packI (lu_int32 h, lu_int32 l) { 374static Rand64 packI (lu_int32 h, lu_int32 l) {
357 Rand64 result; 375 Rand64 result;
358 result.h = h; 376 result.h = h;
@@ -360,16 +378,19 @@ static Rand64 packI (lu_int32 h, lu_int32 l) {
360 return result; 378 return result;
361} 379}
362 380
381/* return i << n */
363static Rand64 Ishl (Rand64 i, int n) { 382static Rand64 Ishl (Rand64 i, int n) {
364 lua_assert(n > 0 && n < 32); 383 lua_assert(n > 0 && n < 32);
365 return packI((i.h << n) | (trim32(i.l) >> (32 - n)), i.l << n); 384 return packI((i.h << n) | (trim32(i.l) >> (32 - n)), i.l << n);
366} 385}
367 386
387/* i1 ^= i2 */
368static void Ixor (Rand64 *i1, Rand64 i2) { 388static void Ixor (Rand64 *i1, Rand64 i2) {
369 i1->h ^= i2.h; 389 i1->h ^= i2.h;
370 i1->l ^= i2.l; 390 i1->l ^= i2.l;
371} 391}
372 392
393/* return i1 + i2 */
373static Rand64 Iadd (Rand64 i1, Rand64 i2) { 394static Rand64 Iadd (Rand64 i1, Rand64 i2) {
374 Rand64 result = packI(i1.h + i2.h, i1.l + i2.l); 395 Rand64 result = packI(i1.h + i2.h, i1.l + i2.l);
375 if (trim32(result.l) < trim32(i1.l)) /* carry? */ 396 if (trim32(result.l) < trim32(i1.l)) /* carry? */
@@ -377,14 +398,17 @@ static Rand64 Iadd (Rand64 i1, Rand64 i2) {
377 return result; 398 return result;
378} 399}
379 400
401/* return i * 5 */
380static Rand64 times5 (Rand64 i) { 402static Rand64 times5 (Rand64 i) {
381 return Iadd(Ishl(i, 2), i); /* i * 5 == (i << 2) + i */ 403 return Iadd(Ishl(i, 2), i); /* i * 5 == (i << 2) + i */
382} 404}
383 405
406/* return i * 9 */
384static Rand64 times9 (Rand64 i) { 407static Rand64 times9 (Rand64 i) {
385 return Iadd(Ishl(i, 3), i); /* i * 9 == (i << 3) + i */ 408 return Iadd(Ishl(i, 3), i); /* i * 9 == (i << 3) + i */
386} 409}
387 410
411/* return 'i' rotated left 'n' bits */
388static Rand64 rotl (Rand64 i, int n) { 412static Rand64 rotl (Rand64 i, int n) {
389 lua_assert(n > 0 && n < 32); 413 lua_assert(n > 0 && n < 32);
390 return packI((i.h << n) | (trim32(i.l) >> (32 - n)), 414 return packI((i.h << n) | (trim32(i.l) >> (32 - n)),
@@ -416,7 +440,7 @@ static Rand64 nextrand (Rand64 *state) {
416 440
417 441
418/* 442/*
419** Converts an 'Rand64' into a float. 443** Converts a 'Rand64' into a float.
420*/ 444*/
421 445
422/* an unsigned 1 with proper type */ 446/* an unsigned 1 with proper type */
@@ -452,11 +476,12 @@ static lua_Number I2d (Rand64 x) {
452} 476}
453 477
454 478
479/* convert a 'Rand64' to a 'lua_Unsigned' */
455static lua_Unsigned I2UInt (Rand64 x) { 480static lua_Unsigned I2UInt (Rand64 x) {
456 return ((lua_Unsigned)x.h << 31 << 1) | (lua_Unsigned)trim32(x.l); 481 return ((lua_Unsigned)trim32(x.h) << 31 << 1) | (lua_Unsigned)trim32(x.l);
457} 482}
458 483
459 484/* convert a 'lua_Unsigned' to a 'Rand64' */
460static Rand64 Int2I (lua_Unsigned n) { 485static Rand64 Int2I (lua_Unsigned n) {
461 return packI((lu_int32)(n >> 31 >> 1), (lu_int32)n); 486 return packI((lu_int32)(n >> 31 >> 1), (lu_int32)n);
462} 487}
@@ -479,7 +504,7 @@ typedef struct {
479** division). To get a uniform projection into [0, n], we first compute 504** division). To get a uniform projection into [0, n], we first compute
480** 'lim', the smallest Mersenne number not smaller than 'n'. We then 505** 'lim', the smallest Mersenne number not smaller than 'n'. We then
481** project 'ran' into the interval [0, lim]. If the result is inside 506** project 'ran' into the interval [0, lim]. If the result is inside
482** [0, n], we are done. Otherwise, we try with another 'ran' until we 507** [0, n], we are done. Otherwise, we try with another 'ran', until we
483** have a result inside the interval. 508** have a result inside the interval.
484*/ 509*/
485static lua_Unsigned project (lua_Unsigned ran, lua_Unsigned n, 510static lua_Unsigned project (lua_Unsigned ran, lua_Unsigned n,
@@ -492,15 +517,15 @@ static lua_Unsigned project (lua_Unsigned ran, lua_Unsigned n,
492 lim |= (lim >> 4); 517 lim |= (lim >> 4);
493 lim |= (lim >> 8); 518 lim |= (lim >> 8);
494 lim |= (lim >> 16); 519 lim |= (lim >> 16);
495#if (LUA_MAXINTEGER >> 30 >> 2) > 0 520#if (LUA_MAXINTEGER >> 30 >> 1) > 0
496 lim |= (lim >> 32); /* integer type has more than 32 bits */ 521 lim |= (lim >> 32); /* integer type has more than 32 bits */
497#endif 522#endif
498 } 523 }
499 lua_assert((lim & (lim + 1)) == 0 /* 'lim + 1' is a power of 2 */ 524 lua_assert((lim & (lim + 1)) == 0 /* 'lim + 1' is a power of 2, */
500 && lim >= n /* not smaller than 'n' */ 525 && lim >= n /* not smaller than 'n', */
501 && (lim == 0 || (lim >> 1) < n)); /* it is the smallest one */ 526 && (lim == 0 || (lim >> 1) < n)); /* and it is the smallest one */
502 while ((ran &= lim) > n) 527 while ((ran &= lim) > n) /* project 'ran' into [0..lim] */
503 ran = I2UInt(nextrand(state->s)); 528 ran = I2UInt(nextrand(state->s)); /* not inside [0..n]? try again */
504 return ran; 529 return ran;
505} 530}
506 531