diff --git a/libguile/numbers.c b/libguile/numbers.c index 1d9a86f78..2bb5c99d0 100644 --- a/libguile/numbers.c +++ b/libguile/numbers.c @@ -234,9 +234,12 @@ scm_i_make_ratio_already_reduced (SCM numerator, SCM denominator) if (scm_is_eq (denominator, SCM_INUM1)) return numerator; - return scm_double_cell (scm_tc16_fraction, - SCM_UNPACK (numerator), - SCM_UNPACK (denominator), 0); + struct scm_fraction *f = scm_allocate_tagged (SCM_I_CURRENT_THREAD, + sizeof (*f)); + f->tag = scm_tc16_fraction; + f->numerator = numerator; + f->denominator = denominator; + return scm_from_fraction (f); } static SCM scm_exact_integer_quotient (SCM x, SCM y); @@ -3571,7 +3574,6 @@ scm_i_print_double (double val, SCM port) int scm_print_complex (SCM sexp, SCM port, scm_print_state *pstate SCM_UNUSED) - { char num_buf[FLOBUFLEN]; scm_lfwrite (num_buf, iflo2str (sexp, num_buf, 10), port); diff --git a/libguile/numbers.h b/libguile/numbers.h index 84ad5466f..2561be825 100644 --- a/libguile/numbers.h +++ b/libguile/numbers.h @@ -1,7 +1,7 @@ #ifndef SCM_NUMBERS_H #define SCM_NUMBERS_H -/* Copyright 1995-1996,1998,2000-2006,2008-2011,2013-2014,2016-2018,2021-2022 +/* Copyright 1995-1996,1998,2000-2006,2008-2011,2013-2014,2016-2018,2021-2022,2025 Free Software Foundation, Inc. This file is part of Guile. @@ -171,31 +171,72 @@ typedef long scm_t_inum; #define SCM_NUMBERP(x) (SCM_I_INUMP(x) || SCM_NUMP(x)) #define SCM_NUMP(x) (SCM_HAS_TYP7 (x, scm_tc7_number)) -#define SCM_FRACTIONP(x) (SCM_HAS_TYP16 (x, scm_tc16_fraction)) -#define SCM_FRACTION_NUMERATOR(x) (SCM_CELL_OBJECT_1 (x)) -#define SCM_FRACTION_DENOMINATOR(x) (SCM_CELL_OBJECT_2 (x)) - typedef struct scm_t_double { - SCM type; + scm_t_bits type; #if SCM_SIZEOF_UINTPTR_T != 8 - SCM pad; + scm_t_bits pad; #endif double real; } scm_t_double; typedef struct scm_t_complex { - SCM type; + scm_t_bits type; #if SCM_SIZEOF_UINTPTR_T != 8 - SCM pad; + scm_t_bits pad; #endif double real; double imag; } scm_t_complex; +struct scm_fraction +{ + scm_t_bits tag; + SCM numerator; + SCM denominator; +}; + + + +static inline int +scm_is_fraction (SCM x) +{ + return SCM_HAS_TYP16 (x, scm_tc16_fraction); +} + +static inline struct scm_fraction * +scm_to_fraction (SCM x) +{ + if (!scm_is_fraction (x)) + abort (); + return (struct scm_fraction *) SCM_UNPACK_POINTER (x); +} + +static inline SCM +scm_from_fraction (struct scm_fraction *f) +{ + return SCM_PACK_POINTER (f); +} + +static inline SCM +scm_fraction_numerator (struct scm_fraction *f) +{ + return f->numerator; +} + +static inline SCM +scm_fraction_denominator (struct scm_fraction *f) +{ + return f->denominator; +} + +#define SCM_FRACTIONP(x) (scm_is_fraction (x)) +#define SCM_FRACTION_NUMERATOR(x) (scm_fraction_numerator (scm_to_fraction (x))) +#define SCM_FRACTION_DENOMINATOR(x) (scm_fraction_denominator (scm_to_fraction (x))) + SCM_API SCM scm_exact_p (SCM x);