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 | ||
