mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 11:50:28 +02:00
SCM_SRS: Improve fallback implemention to avoid unspecified behavior.
* libguile/numbers.h (SCM_SRS): Rewrite preprocessor test to avoid left-shifting negative integers, and to test more comprehensively for the behavior we need. Rewrite fallback implementation to avoid unspecified behavior.
This commit is contained in:
parent
7f8ad91b99
commit
e293c94c65
1 changed files with 14 additions and 5 deletions
|
@ -49,12 +49,21 @@ typedef scm_t_int32 scm_t_wchar;
|
||||||
#define SCM_MOST_POSITIVE_FIXNUM ((SCM_T_SIGNED_BITS_MAX-3)/4)
|
#define SCM_MOST_POSITIVE_FIXNUM ((SCM_T_SIGNED_BITS_MAX-3)/4)
|
||||||
#define SCM_MOST_NEGATIVE_FIXNUM (-SCM_MOST_POSITIVE_FIXNUM-1)
|
#define SCM_MOST_NEGATIVE_FIXNUM (-SCM_MOST_POSITIVE_FIXNUM-1)
|
||||||
|
|
||||||
/* SCM_SRS is signed right shift */
|
/* SCM_SRS (X, Y) is signed right shift, defined as floor (X / 2^Y),
|
||||||
#if (-1 == (((-1) << 2) + 2) >> 2)
|
where Y must be non-negative and less than the width in bits of X.
|
||||||
# define SCM_SRS(x, y) ((x) >> (y))
|
It's common for >> to do this, but the C standards do not specify
|
||||||
|
what happens when X is negative.
|
||||||
|
|
||||||
|
NOTE: X must not perform side effects. */
|
||||||
|
#if (-1 >> 2 == -1) && (-4 >> 2 == -1) && (-5 >> 2 == -2) && (-8 >> 2 == -2)
|
||||||
|
# define SCM_SRS(x, y) ((x) >> (y))
|
||||||
#else
|
#else
|
||||||
# define SCM_SRS(x, y) ((x) < 0 ? ~((~(x)) >> (y)) : ((x) >> (y)))
|
# define SCM_SRS(x, y) \
|
||||||
#endif /* (-1 == (((-1) << 2) + 2) >> 2) */
|
((x) < 0 \
|
||||||
|
? -1 - (scm_t_signed_bits) (~(scm_t_bits)(x) >> (y)) \
|
||||||
|
: ((x) >> (y)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define SCM_I_INUMP(x) (2 & SCM_UNPACK (x))
|
#define SCM_I_INUMP(x) (2 & SCM_UNPACK (x))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue