aboutsummaryrefslogtreecommitdiff
path: root/lmathlib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-11-07 17:25:46 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-11-07 17:25:46 -0300
commit9e99f3071d07767f9e882c4abf3537f75ce2d161 (patch)
treea547cbf1772bae35b9c0d842799db0dbf2d27012 /lmathlib.c
parent14e416355f83cf0a1b871eedec2c92b86dbe76d6 (diff)
parent7923dbbf72da303ca1cca17efd24725668992f15 (diff)
downloadlua-9e99f3071d07767f9e882c4abf3537f75ce2d161.tar.gz
lua-9e99f3071d07767f9e882c4abf3537f75ce2d161.tar.bz2
lua-9e99f3071d07767f9e882c4abf3537f75ce2d161.zip
Merge branch 'master' into nextversion
Diffstat (limited to 'lmathlib.c')
-rw-r--r--lmathlib.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/lmathlib.c b/lmathlib.c
index 6d63950c..c0a75f06 100644
--- a/lmathlib.c
+++ b/lmathlib.c
@@ -249,6 +249,15 @@ static int math_type (lua_State *L) {
249** =================================================================== 249** ===================================================================
250*/ 250*/
251 251
252/*
253** This code uses lots of shifts. ANSI C does not allow shifts greater
254** than or equal to the width of the type being shifted, so some shifts
255** are written in convoluted ways to match that restriction. For
256** preprocessor tests, it assumes a width of 32 bits, so the maximum
257** shift there is 31 bits.
258*/
259
260
252/* number of binary digits in the mantissa of a float */ 261/* number of binary digits in the mantissa of a float */
253#define FIGS l_floatatt(MANT_DIG) 262#define FIGS l_floatatt(MANT_DIG)
254 263
@@ -271,16 +280,19 @@ static int math_type (lua_State *L) {
271 280
272/* 'long' has at least 64 bits */ 281/* 'long' has at least 64 bits */
273#define Rand64 unsigned long 282#define Rand64 unsigned long
283#define SRand64 long
274 284
275#elif !defined(LUA_USE_C89) && defined(LLONG_MAX) 285#elif !defined(LUA_USE_C89) && defined(LLONG_MAX)
276 286
277/* there is a 'long long' type (which must have at least 64 bits) */ 287/* there is a 'long long' type (which must have at least 64 bits) */
278#define Rand64 unsigned long long 288#define Rand64 unsigned long long
289#define SRand64 long long
279 290
280#elif ((LUA_MAXUNSIGNED >> 31) >> 31) >= 3 291#elif ((LUA_MAXUNSIGNED >> 31) >> 31) >= 3
281 292
282/* 'lua_Unsigned' has at least 64 bits */ 293/* 'lua_Unsigned' has at least 64 bits */
283#define Rand64 lua_Unsigned 294#define Rand64 lua_Unsigned
295#define SRand64 lua_Integer
284 296
285#endif 297#endif
286 298
@@ -319,23 +331,30 @@ static Rand64 nextrand (Rand64 *state) {
319} 331}
320 332
321 333
322/* must take care to not shift stuff by more than 63 slots */
323
324
325/* 334/*
326** Convert bits from a random integer into a float in the 335** Convert bits from a random integer into a float in the
327** interval [0,1), getting the higher FIG bits from the 336** interval [0,1), getting the higher FIG bits from the
328** random unsigned integer and converting that to a float. 337** random unsigned integer and converting that to a float.
338** Some old Microsoft compilers cannot cast an unsigned long
339** to a floating-point number, so we use a signed long as an
340** intermediary. When lua_Number is float or double, the shift ensures
341** that 'sx' is non negative; in that case, a good compiler will remove
342** the correction.
329*/ 343*/
330 344
331/* must throw out the extra (64 - FIGS) bits */ 345/* must throw out the extra (64 - FIGS) bits */
332#define shift64_FIG (64 - FIGS) 346#define shift64_FIG (64 - FIGS)
333 347
334/* to scale to [0, 1), multiply by scaleFIG = 2^(-FIGS) */ 348/* 2^(-FIGS) == 2^-1 / 2^(FIGS-1) */
335#define scaleFIG (l_mathop(0.5) / ((Rand64)1 << (FIGS - 1))) 349#define scaleFIG (l_mathop(0.5) / ((Rand64)1 << (FIGS - 1)))
336 350
337static lua_Number I2d (Rand64 x) { 351static lua_Number I2d (Rand64 x) {
338 return (lua_Number)(trim64(x) >> shift64_FIG) * scaleFIG; 352 SRand64 sx = (SRand64)(trim64(x) >> shift64_FIG);
353 lua_Number res = (lua_Number)(sx) * scaleFIG;
354 if (sx < 0)
355 res += 1.0; /* correct the two's complement if negative */
356 lua_assert(0 <= res && res < 1);
357 return res;
339} 358}
340 359
341/* convert a 'Rand64' to a 'lua_Unsigned' */ 360/* convert a 'Rand64' to a 'lua_Unsigned' */
@@ -471,8 +490,6 @@ static lua_Number I2d (Rand64 x) {
471 490
472#else /* 32 < FIGS <= 64 */ 491#else /* 32 < FIGS <= 64 */
473 492
474/* must take care to not shift stuff by more than 31 slots */
475
476/* 2^(-FIGS) = 1.0 / 2^30 / 2^3 / 2^(FIGS-33) */ 493/* 2^(-FIGS) = 1.0 / 2^30 / 2^3 / 2^(FIGS-33) */
477#define scaleFIG \ 494#define scaleFIG \
478 (l_mathop(1.0) / (UONE << 30) / l_mathop(8.0) / (UONE << (FIGS - 33))) 495 (l_mathop(1.0) / (UONE << 30) / l_mathop(8.0) / (UONE << (FIGS - 33)))