From cdd337f3aaaf524130ac5e27e578f8766d0f6da4 Mon Sep 17 00:00:00 2001 From: Alex Shinn Date: Sat, 22 Dec 2012 03:28:58 +0000 Subject: [PATCH] Switching to using a union instead of type-cast to get at the bits of a flonum for eqv? comparison. Fixes issue #164. --- include/chibi/sexp.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/chibi/sexp.h b/include/chibi/sexp.h index 60e93a24..7434a07a 100755 --- a/include/chibi/sexp.h +++ b/include/chibi/sexp.h @@ -301,6 +301,7 @@ struct sexp_struct { union { /* basic types */ double flonum; + char flonum_bits[sizeof(double)]; /* for eqv? comparison on flonums */ struct sexp_type_struct type; struct { sexp car, cdr; @@ -609,6 +610,7 @@ union sexp_flonum_conv { SEXP_API sexp sexp_flonum_predicate (sexp ctx, sexp x); #if SEXP_64_BIT SEXP_API float sexp_flonum_value (sexp x); +#define sexp_flonum_bits(f) ((char*)&f) SEXP_API sexp sexp_make_flonum(sexp ctx, float f); #else #define sexp_make_flonum(ctx, x) ((sexp) ((((union sexp_flonum_conv)((float)(x))).bits & ~SEXP_IMMEDIATE_MASK) + SEXP_IFLONUM_TAG)) @@ -617,6 +619,7 @@ SEXP_API sexp sexp_make_flonum(sexp ctx, float f); #else #define sexp_flonump(x) (sexp_check_tag(x, SEXP_FLONUM)) #define sexp_flonum_value(f) ((f)->value.flonum) +#define sexp_flonum_bits(f) ((f)->value.flonum_bits) sexp sexp_make_flonum(sexp ctx, double f); #endif @@ -821,8 +824,7 @@ SEXP_API sexp sexp_make_unsigned_integer(sexp ctx, sexp_luint_t x); #define sexp_nanp(x) (sexp_flonump(x) && isnan(sexp_flonum_value(x))) #if SEXP_USE_IEEE_EQV -#define sexp_flonum_bits(x) (*(long*)(&(sexp_flonum_value(x)))) -#define sexp_flonum_eqv(x, y) (sexp_flonum_bits(x) == sexp_flonum_bits(y)) +#define sexp_flonum_eqv(x, y) (memcmp(sexp_flonum_bits(x), sexp_flonum_bits(y), sizeof(double)) == 0) #else #define sexp_flonum_eqv(x, y) (sexp_flonum_value(x) == sexp_flonum_value(y)) #endif