diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-05-04 17:01:45 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-05-04 17:01:45 -0300 |
commit | 3e7415e846f2f75ed29e27e1211205ea6243e0c7 (patch) | |
tree | 6c7fd1371648cd62f4ead5f9f25cb2e46a42b11d /lmathlib.c | |
parent | e64e20ac8136b6cf53601127fc5c69310d644eeb (diff) | |
download | lua-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.c | 87 |
1 files changed, 56 insertions, 31 deletions
@@ -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 */ | ||
269 | typedef 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 | ||
329 | typedef unsigned int lu_int32; | 344 | typedef unsigned int lu_int32; |
330 | #else | 345 | #else |
331 | typedef unsigned long lu_int32; | 346 | typedef 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 | */ | ||
336 | typedef struct Rand64 { | 353 | typedef 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 */ | ||
356 | static Rand64 packI (lu_int32 h, lu_int32 l) { | 374 | static 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 */ | ||
363 | static Rand64 Ishl (Rand64 i, int n) { | 382 | static 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 */ | ||
368 | static void Ixor (Rand64 *i1, Rand64 i2) { | 388 | static 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 */ | ||
373 | static Rand64 Iadd (Rand64 i1, Rand64 i2) { | 394 | static 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 */ | ||
380 | static Rand64 times5 (Rand64 i) { | 402 | static 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 */ | ||
384 | static Rand64 times9 (Rand64 i) { | 407 | static 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 */ | ||
388 | static Rand64 rotl (Rand64 i, int n) { | 412 | static 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' */ | ||
455 | static lua_Unsigned I2UInt (Rand64 x) { | 480 | static 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' */ | |
460 | static Rand64 Int2I (lua_Unsigned n) { | 485 | static 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 | */ |
485 | static lua_Unsigned project (lua_Unsigned ran, lua_Unsigned n, | 510 | static 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 | ||