mathimp.c revision 5dfecf96
15dfecf96Smrg/* 25dfecf96Smrg * Copyright (c) 2002 by The XFree86 Project, Inc. 35dfecf96Smrg * 45dfecf96Smrg * Permission is hereby granted, free of charge, to any person obtaining a 55dfecf96Smrg * copy of this software and associated documentation files (the "Software"), 65dfecf96Smrg * to deal in the Software without restriction, including without limitation 75dfecf96Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 85dfecf96Smrg * and/or sell copies of the Software, and to permit persons to whom the 95dfecf96Smrg * Software is furnished to do so, subject to the following conditions: 105dfecf96Smrg * 115dfecf96Smrg * The above copyright notice and this permission notice shall be included in 125dfecf96Smrg * all copies or substantial portions of the Software. 135dfecf96Smrg * 145dfecf96Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 155dfecf96Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 165dfecf96Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 175dfecf96Smrg * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 185dfecf96Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 195dfecf96Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 205dfecf96Smrg * SOFTWARE. 215dfecf96Smrg * 225dfecf96Smrg * Except as contained in this notice, the name of the XFree86 Project shall 235dfecf96Smrg * not be used in advertising or otherwise to promote the sale, use or other 245dfecf96Smrg * dealings in this Software without prior written authorization from the 255dfecf96Smrg * XFree86 Project. 265dfecf96Smrg * 275dfecf96Smrg * Author: Paulo César Pereira de Andrade 285dfecf96Smrg */ 295dfecf96Smrg 305dfecf96Smrg/* $XFree86: xc/programs/xedit/lisp/mathimp.c,v 1.14tsi Exp $ */ 315dfecf96Smrg 325dfecf96Smrg 335dfecf96Smrg/* 345dfecf96Smrg * Defines 355dfecf96Smrg */ 365dfecf96Smrg#ifdef __GNUC__ 375dfecf96Smrg#define CONST __attribute__ ((__const__)) 385dfecf96Smrg#else 395dfecf96Smrg#define CONST /**/ 405dfecf96Smrg#endif 415dfecf96Smrg 425dfecf96Smrg/* mask for checking overflow on long operations */ 435dfecf96Smrg#ifdef LONG64 445dfecf96Smrg#define FI_MASK 0x4000000000000000L 455dfecf96Smrg#define LONGSBITS 63 465dfecf96Smrg#else 475dfecf96Smrg#define FI_MASK 0x40000000L 485dfecf96Smrg#define LONGSBITS 31 495dfecf96Smrg#endif 505dfecf96Smrg 515dfecf96Smrg#define N_FIXNUM 1 525dfecf96Smrg#define N_BIGNUM 2 535dfecf96Smrg#define N_FLONUM 3 545dfecf96Smrg#define N_FIXRATIO 4 555dfecf96Smrg#define N_BIGRATIO 5 565dfecf96Smrg 575dfecf96Smrg#define NOP_ADD 1 585dfecf96Smrg#define NOP_SUB 2 595dfecf96Smrg#define NOP_MUL 3 605dfecf96Smrg#define NOP_DIV 4 615dfecf96Smrg 625dfecf96Smrg#define NDIVIDE_CEIL 1 635dfecf96Smrg#define NDIVIDE_FLOOR 2 645dfecf96Smrg#define NDIVIDE_ROUND 3 655dfecf96Smrg#define NDIVIDE_TRUNC 4 665dfecf96Smrg 675dfecf96Smrg/* real part from number */ 685dfecf96Smrg#define NREAL(num) &((num)->real) 695dfecf96Smrg#define NRTYPE(num) (num)->real.type 705dfecf96Smrg#define NRFI(num) (num)->real.data.fixnum 715dfecf96Smrg#define NRBI(num) (num)->real.data.bignum 725dfecf96Smrg#define NRFF(num) (num)->real.data.flonum 735dfecf96Smrg#define NRFRN(Num) (Num)->real.data.fixratio.num 745dfecf96Smrg#define NRFRD(num) (num)->real.data.fixratio.den 755dfecf96Smrg#define NRBR(num) (num)->real.data.bigratio 765dfecf96Smrg#define NRBRN(num) mpr_num(NRBR(num)) 775dfecf96Smrg#define NRBRD(num) mpr_den(NRBR(num)) 785dfecf96Smrg 795dfecf96Smrg#define NRCLEAR_BI(num) mpi_clear(NRBI(num)); XFREE(NRBI(num)) 805dfecf96Smrg#define NRCLEAR_BR(num) mpr_clear(NRBR(num)); XFREE(NRBR(num)) 815dfecf96Smrg 825dfecf96Smrg/* imag part from number */ 835dfecf96Smrg#define NIMAG(num) &((num)->imag) 845dfecf96Smrg#define NITYPE(num) (num)->imag.type 855dfecf96Smrg#define NIFI(num) (num)->imag.data.fixnum 865dfecf96Smrg#define NIBI(num) (num)->imag.data.bignum 875dfecf96Smrg#define NIFF(num) (num)->imag.data.flonum 885dfecf96Smrg#define NIFRN(Num) (Num)->imag.data.fixratio.num 895dfecf96Smrg#define NIFRD(num) (num)->imag.data.fixratio.den 905dfecf96Smrg#define NIBR(num) (num)->imag.data.bigratio 915dfecf96Smrg#define NIBRN(obj) mpr_num(NIBR(obj)) 925dfecf96Smrg#define NIBRD(obj) mpr_den(NIBR(obj)) 935dfecf96Smrg 945dfecf96Smrg/* real number fields */ 955dfecf96Smrg#define RTYPE(real) (real)->type 965dfecf96Smrg#define RFI(real) (real)->data.fixnum 975dfecf96Smrg#define RBI(real) (real)->data.bignum 985dfecf96Smrg#define RFF(real) (real)->data.flonum 995dfecf96Smrg#define RFRN(real) (real)->data.fixratio.num 1005dfecf96Smrg#define RFRD(real) (real)->data.fixratio.den 1015dfecf96Smrg#define RBR(real) (real)->data.bigratio 1025dfecf96Smrg#define RBRN(real) mpr_num(RBR(real)) 1035dfecf96Smrg#define RBRD(real) mpr_den(RBR(real)) 1045dfecf96Smrg 1055dfecf96Smrg#define RINTEGERP(real) \ 1065dfecf96Smrg (RTYPE(real) == N_FIXNUM || RTYPE(real) == N_BIGNUM) 1075dfecf96Smrg 1085dfecf96Smrg#define RCLEAR_BI(real) mpi_clear(RBI(real)); XFREE(RBI(real)) 1095dfecf96Smrg#define RCLEAR_BR(real) mpr_clear(RBR(real)); XFREE(RBR(real)) 1105dfecf96Smrg 1115dfecf96Smrg/* numeric value from lisp object */ 1125dfecf96Smrg#define OFI(object) FIXNUM_VALUE(object) 1135dfecf96Smrg#define OII(object) INT_VALUE(object) 1145dfecf96Smrg#define OBI(object) (object)->data.mp.integer 1155dfecf96Smrg#define ODF(object) DFLOAT_VALUE(object) 1165dfecf96Smrg#define OFRN(object) (object)->data.ratio.numerator 1175dfecf96Smrg#define OFRD(object) (object)->data.ratio.denominator 1185dfecf96Smrg#define OBR(object) (object)->data.mp.ratio 1195dfecf96Smrg#define OBRN(object) mpr_num(OBR(object)) 1205dfecf96Smrg#define OBRD(object) mpr_den(OBR(object)) 1215dfecf96Smrg#define OCXR(object) (object)->data.complex.real 1225dfecf96Smrg#define OCXI(object) (object)->data.complex.imag 1235dfecf96Smrg 1245dfecf96Smrg#define XALLOC(type) LispMalloc(sizeof(type)) 1255dfecf96Smrg#define XFREE(ptr) LispFree(ptr) 1265dfecf96Smrg 1275dfecf96Smrg 1285dfecf96Smrg/* 1295dfecf96Smrg * Types 1305dfecf96Smrg */ 1315dfecf96Smrgtypedef struct _n_real { 1325dfecf96Smrg char type; 1335dfecf96Smrg union { 1345dfecf96Smrg long fixnum; 1355dfecf96Smrg mpi *bignum; 1365dfecf96Smrg double flonum; 1375dfecf96Smrg struct { 1385dfecf96Smrg long num; 1395dfecf96Smrg long den; 1405dfecf96Smrg } fixratio; 1415dfecf96Smrg mpr *bigratio; 1425dfecf96Smrg } data; 1435dfecf96Smrg} n_real; 1445dfecf96Smrg 1455dfecf96Smrgtypedef struct _n_number { 1465dfecf96Smrg char complex; 1475dfecf96Smrg n_real real; 1485dfecf96Smrg n_real imag; 1495dfecf96Smrg} n_number; 1505dfecf96Smrg 1515dfecf96Smrg 1525dfecf96Smrg/* 1535dfecf96Smrg * Prototypes 1545dfecf96Smrg */ 1555dfecf96Smrgstatic void number_init(void); 1565dfecf96Smrgstatic LispObj *number_pi(void); 1575dfecf96Smrg 1585dfecf96Smrgstatic void set_real_real(n_real*, n_real*); 1595dfecf96Smrgstatic void set_real_object(n_real*, LispObj*); 1605dfecf96Smrgstatic void set_number_object(n_number*, LispObj*); 1615dfecf96Smrgstatic void clear_real(n_real*); 1625dfecf96Smrgstatic void clear_number(n_number*); 1635dfecf96Smrg 1645dfecf96Smrgstatic LispObj *make_real_object(n_real*); 1655dfecf96Smrgstatic LispObj *make_number_object(n_number*); 1665dfecf96Smrg 1675dfecf96Smrgstatic void fatal_error(int); 1685dfecf96Smrgstatic void fatal_object_error(LispObj*, int); 1695dfecf96Smrgstatic void fatal_builtin_object_error(LispBuiltin*, LispObj*, int); 1705dfecf96Smrg 1715dfecf96Smrgstatic double bi_getd(mpi*); 1725dfecf96Smrgstatic double br_getd(mpr*); 1735dfecf96Smrg 1745dfecf96Smrg/* add */ 1755dfecf96Smrgstatic void add_real_object(n_real*, LispObj*); 1765dfecf96Smrgstatic void add_number_object(n_number*, LispObj*); 1775dfecf96Smrg 1785dfecf96Smrg/* sub */ 1795dfecf96Smrgstatic void sub_real_object(n_real*, LispObj*); 1805dfecf96Smrgstatic void sub_number_object(n_number*, LispObj*); 1815dfecf96Smrg 1825dfecf96Smrg/* mul */ 1835dfecf96Smrgstatic void mul_real_object(n_real*, LispObj*); 1845dfecf96Smrgstatic void mul_number_object(n_number*, LispObj*); 1855dfecf96Smrg 1865dfecf96Smrg/* div */ 1875dfecf96Smrgstatic void div_real_object(n_real*, LispObj*); 1885dfecf96Smrgstatic void div_number_object(n_number*, LispObj*); 1895dfecf96Smrg 1905dfecf96Smrg/* compare */ 1915dfecf96Smrgstatic int cmp_real_real(n_real*, n_real*); 1925dfecf96Smrgstatic int cmp_real_object(n_real*, LispObj*); 1935dfecf96Smrg#if 0 /* not used */ 1945dfecf96Smrgstatic int cmp_number_object(n_number*, LispObj*); 1955dfecf96Smrg#endif 1965dfecf96Smrgstatic int cmp_object_object(LispObj*, LispObj*, int); 1975dfecf96Smrg 1985dfecf96Smrg/* fixnum */ 1995dfecf96Smrgstatic INLINE int fi_fi_add_overflow(long, long) CONST; 2005dfecf96Smrgstatic INLINE int fi_fi_sub_overflow(long, long) CONST; 2015dfecf96Smrgstatic INLINE int fi_fi_mul_overflow(long, long) CONST; 2025dfecf96Smrg 2035dfecf96Smrg/* bignum */ 2045dfecf96Smrgstatic void rbi_canonicalize(n_real*); 2055dfecf96Smrg 2065dfecf96Smrg/* ratio */ 2075dfecf96Smrgstatic void rfr_canonicalize(n_real*); 2085dfecf96Smrgstatic void rbr_canonicalize(n_real*); 2095dfecf96Smrg 2105dfecf96Smrg/* complex */ 2115dfecf96Smrgstatic void ncx_canonicalize(n_number*); 2125dfecf96Smrg 2135dfecf96Smrg/* abs */ 2145dfecf96Smrgstatic void abs_real(n_real*); 2155dfecf96Smrgstatic void abs_number(n_number*); 2165dfecf96Smrgstatic void nabs_cx(n_number*); 2175dfecf96Smrgstatic INLINE void rabs_fi(n_real*); 2185dfecf96Smrgstatic INLINE void rabs_bi(n_real*); 2195dfecf96Smrgstatic INLINE void rabs_ff(n_real*); 2205dfecf96Smrgstatic INLINE void rabs_fr(n_real*); 2215dfecf96Smrgstatic INLINE void rabs_br(n_real*); 2225dfecf96Smrg 2235dfecf96Smrg/* neg */ 2245dfecf96Smrgstatic void neg_real(n_real*); 2255dfecf96Smrgstatic void neg_number(n_number*); 2265dfecf96Smrgstatic void rneg_fi(n_real*); 2275dfecf96Smrgstatic INLINE void rneg_bi(n_real*); 2285dfecf96Smrgstatic INLINE void rneg_ff(n_real*); 2295dfecf96Smrgstatic INLINE void rneg_fr(n_real*); 2305dfecf96Smrgstatic INLINE void rneg_br(n_real*); 2315dfecf96Smrg 2325dfecf96Smrg/* sqrt */ 2335dfecf96Smrgstatic void sqrt_real(n_real*); 2345dfecf96Smrgstatic void sqrt_number(n_number*); 2355dfecf96Smrgstatic void rsqrt_xi(n_real*); 2365dfecf96Smrgstatic void rsqrt_xr(n_real*); 2375dfecf96Smrgstatic void rsqrt_ff(n_real*); 2385dfecf96Smrgstatic void nsqrt_cx(n_number*); 2395dfecf96Smrgstatic void nsqrt_xi(n_number*); 2405dfecf96Smrgstatic void nsqrt_ff(n_number*); 2415dfecf96Smrgstatic void nsqrt_xr(n_number*); 2425dfecf96Smrg 2435dfecf96Smrg/* mod */ 2445dfecf96Smrgstatic void mod_real_real(n_real*, n_real*); 2455dfecf96Smrgstatic void mod_real_object(n_real*, LispObj*); 2465dfecf96Smrgstatic void rmod_fi_fi(n_real*, long); 2475dfecf96Smrgstatic void rmod_fi_bi(n_real*, mpi*); 2485dfecf96Smrgstatic void rmod_bi_fi(n_real*, long); 2495dfecf96Smrgstatic void rmod_bi_bi(n_real*, mpi*); 2505dfecf96Smrg 2515dfecf96Smrg/* rem */ 2525dfecf96Smrgstatic void rem_real_object(n_real*, LispObj*); 2535dfecf96Smrgstatic void rrem_fi_fi(n_real*, long); 2545dfecf96Smrgstatic void rrem_fi_bi(n_real*, mpi*); 2555dfecf96Smrgstatic void rrem_bi_fi(n_real*, long); 2565dfecf96Smrgstatic void rrem_bi_bi(n_real*, mpi*); 2575dfecf96Smrg 2585dfecf96Smrg/* gcd */ 2595dfecf96Smrgstatic void gcd_real_object(n_real*, LispObj*); 2605dfecf96Smrg 2615dfecf96Smrg/* and */ 2625dfecf96Smrgstatic void and_real_object(n_real*, LispObj*); 2635dfecf96Smrg 2645dfecf96Smrg/* eqv */ 2655dfecf96Smrgstatic void eqv_real_object(n_real*, LispObj*); 2665dfecf96Smrg 2675dfecf96Smrg/* ior */ 2685dfecf96Smrgstatic void ior_real_object(n_real*, LispObj*); 2695dfecf96Smrg 2705dfecf96Smrg/* not */ 2715dfecf96Smrgstatic void not_real(n_real*); 2725dfecf96Smrg 2735dfecf96Smrg/* xor */ 2745dfecf96Smrgstatic void xor_real_object(n_real*, LispObj*); 2755dfecf96Smrg 2765dfecf96Smrg/* divide */ 2775dfecf96Smrgstatic void divide_number_object(n_number*, LispObj*, int, int); 2785dfecf96Smrgstatic void ndivide_xi_xi(n_number*, LispObj*, int, int); 2795dfecf96Smrgstatic void ndivide_flonum(n_number*, double, double, int, int); 2805dfecf96Smrgstatic void ndivide_xi_xr(n_number*, LispObj*, int, int); 2815dfecf96Smrgstatic void ndivide_xr_xi(n_number*, LispObj*, int, int); 2825dfecf96Smrgstatic void ndivide_xr_xr(n_number*, LispObj*, int, int); 2835dfecf96Smrg 2845dfecf96Smrg/* real complex */ 2855dfecf96Smrgstatic void nadd_re_cx(n_number*, LispObj*); 2865dfecf96Smrgstatic void nsub_re_cx(n_number*, LispObj*); 2875dfecf96Smrgstatic void nmul_re_cx(n_number*, LispObj*); 2885dfecf96Smrgstatic void ndiv_re_cx(n_number*, LispObj*); 2895dfecf96Smrg 2905dfecf96Smrg/* complex real */ 2915dfecf96Smrgstatic void nadd_cx_re(n_number*, LispObj*); 2925dfecf96Smrgstatic void nsub_cx_re(n_number*, LispObj*); 2935dfecf96Smrgstatic void nmul_cx_re(n_number*, LispObj*); 2945dfecf96Smrgstatic void ndiv_cx_re(n_number*, LispObj*); 2955dfecf96Smrg 2965dfecf96Smrg/* complex complex */ 2975dfecf96Smrgstatic void nadd_cx_cx(n_number*, LispObj*); 2985dfecf96Smrgstatic void nsub_cx_cx(n_number*, LispObj*); 2995dfecf96Smrgstatic void nmul_cx_cx(n_number*, LispObj*); 3005dfecf96Smrgstatic void ndiv_cx_cx(n_number*, LispObj*); 3015dfecf96Smrgstatic int cmp_cx_cx(LispObj*, LispObj*); 3025dfecf96Smrg 3035dfecf96Smrg/* flonum flonum */ 3045dfecf96Smrgstatic void radd_flonum(n_real*, double, double); 3055dfecf96Smrgstatic void rsub_flonum(n_real*, double, double); 3065dfecf96Smrgstatic void rmul_flonum(n_real*, double, double); 3075dfecf96Smrgstatic void rdiv_flonum(n_real*, double, double); 3085dfecf96Smrgstatic int cmp_flonum(double, double); 3095dfecf96Smrg 3105dfecf96Smrg/* fixnum fixnum */ 3115dfecf96Smrgstatic void rop_fi_fi_bi(n_real*, long, int); 3125dfecf96Smrgstatic INLINE void radd_fi_fi(n_real*, long); 3135dfecf96Smrgstatic INLINE void rsub_fi_fi(n_real*, long); 3145dfecf96Smrgstatic INLINE void rmul_fi_fi(n_real*, long); 3155dfecf96Smrgstatic INLINE void rdiv_fi_fi(n_real*, long); 3165dfecf96Smrgstatic INLINE int cmp_fi_fi(long, long); 3175dfecf96Smrgstatic void ndivide_fi_fi(n_number*, long, int, int); 3185dfecf96Smrg 3195dfecf96Smrg/* fixnum bignum */ 3205dfecf96Smrgstatic void rop_fi_bi_xi(n_real*, mpi*, int); 3215dfecf96Smrgstatic INLINE void radd_fi_bi(n_real*, mpi*); 3225dfecf96Smrgstatic INLINE void rsub_fi_bi(n_real*, mpi*); 3235dfecf96Smrgstatic INLINE void rmul_fi_bi(n_real*, mpi*); 3245dfecf96Smrgstatic void rdiv_fi_bi(n_real*, mpi*); 3255dfecf96Smrgstatic INLINE int cmp_fi_bi(long, mpi*); 3265dfecf96Smrg 3275dfecf96Smrg/* fixnum fixratio */ 3285dfecf96Smrgstatic void rop_fi_fr_as_xr(n_real*, long, long, int); 3295dfecf96Smrgstatic void rop_fi_fr_md_xr(n_real*, long, long, int); 3305dfecf96Smrgstatic INLINE void radd_fi_fr(n_real*, long, long); 3315dfecf96Smrgstatic INLINE void rsub_fi_fr(n_real*, long, long); 3325dfecf96Smrgstatic INLINE void rmul_fi_fr(n_real*, long, long); 3335dfecf96Smrgstatic INLINE void rdiv_fi_fr(n_real*, long, long); 3345dfecf96Smrgstatic INLINE int cmp_fi_fr(long, long, long); 3355dfecf96Smrg 3365dfecf96Smrg/* fixnum bigratio */ 3375dfecf96Smrgstatic void rop_fi_br_as_xr(n_real*, mpr*, int); 3385dfecf96Smrgstatic void rop_fi_br_md_xr(n_real*, mpr*, int); 3395dfecf96Smrgstatic INLINE void radd_fi_br(n_real*, mpr*); 3405dfecf96Smrgstatic INLINE void rsub_fi_br(n_real*, mpr*); 3415dfecf96Smrgstatic INLINE void rmul_fi_br(n_real*, mpr*); 3425dfecf96Smrgstatic INLINE void rdiv_fi_br(n_real*, mpr*); 3435dfecf96Smrgstatic INLINE int cmp_fi_br(long, mpr*); 3445dfecf96Smrg 3455dfecf96Smrg/* bignum fixnum */ 3465dfecf96Smrgstatic INLINE void radd_bi_fi(n_real*, long); 3475dfecf96Smrgstatic INLINE void rsub_bi_fi(n_real*, long); 3485dfecf96Smrgstatic INLINE void rmul_bi_fi(n_real*, long); 3495dfecf96Smrgstatic void rdiv_bi_fi(n_real*, long); 3505dfecf96Smrgstatic INLINE int cmp_bi_fi(mpi*, long); 3515dfecf96Smrg 3525dfecf96Smrg/* bignum bignum */ 3535dfecf96Smrgstatic INLINE void radd_bi_bi(n_real*, mpi*); 3545dfecf96Smrgstatic INLINE void rsub_bi_bi(n_real*, mpi*); 3555dfecf96Smrgstatic INLINE void rmul_bi_bi(n_real*, mpi*); 3565dfecf96Smrgstatic void rdiv_bi_bi(n_real*, mpi*); 3575dfecf96Smrgstatic INLINE int cmp_bi_bi(mpi*, mpi*); 3585dfecf96Smrg 3595dfecf96Smrg/* bignum fixratio */ 3605dfecf96Smrgstatic void rop_bi_fr_as_xr(n_real*, long, long, int); 3615dfecf96Smrgstatic void rop_bi_fr_md_xr(n_real*, long, long, int); 3625dfecf96Smrgstatic INLINE void radd_bi_fr(n_real*, long, long); 3635dfecf96Smrgstatic INLINE void rsub_bi_fr(n_real*, long, long); 3645dfecf96Smrgstatic INLINE void rmul_bi_fr(n_real*, long, long); 3655dfecf96Smrgstatic INLINE void rdiv_bi_fr(n_real*, long, long); 3665dfecf96Smrgstatic int cmp_bi_fr(mpi*, long, long); 3675dfecf96Smrg 3685dfecf96Smrg/* bignum bigratio */ 3695dfecf96Smrgstatic void rop_bi_br_as_xr(n_real*, mpr*, int); 3705dfecf96Smrgstatic void rop_bi_br_md_xr(n_real*, mpr*, int); 3715dfecf96Smrgstatic INLINE void radd_bi_br(n_real*, mpr*); 3725dfecf96Smrgstatic INLINE void rsub_bi_br(n_real*, mpr*); 3735dfecf96Smrgstatic INLINE void rmul_bi_br(n_real*, mpr*); 3745dfecf96Smrgstatic INLINE void rdiv_bi_br(n_real*, mpr*); 3755dfecf96Smrgstatic int cmp_bi_br(mpi*, mpr*); 3765dfecf96Smrg 3775dfecf96Smrg/* fixratio fixnum */ 3785dfecf96Smrgstatic void rop_fr_fi_as_xr(n_real*, long, int); 3795dfecf96Smrgstatic void rop_fr_fi_md_xr(n_real*, long, int); 3805dfecf96Smrgstatic INLINE void radd_fr_fi(n_real*, long); 3815dfecf96Smrgstatic INLINE void rsub_fr_fi(n_real*, long); 3825dfecf96Smrgstatic INLINE void rmul_fr_fi(n_real*, long); 3835dfecf96Smrgstatic INLINE void rdiv_fr_fi(n_real*, long); 3845dfecf96Smrgstatic INLINE int cmp_fr_fi(long, long, long); 3855dfecf96Smrg 3865dfecf96Smrg/* fixratio bignum */ 3875dfecf96Smrgstatic void rop_fr_bi_as_xr(n_real*, mpi*, int); 3885dfecf96Smrgstatic void rop_fr_bi_md_xr(n_real*, mpi*, int); 3895dfecf96Smrgstatic INLINE void radd_fr_bi(n_real*, mpi*); 3905dfecf96Smrgstatic INLINE void rsub_fr_bi(n_real*, mpi*); 3915dfecf96Smrgstatic INLINE void rmul_fr_bi(n_real*, mpi*); 3925dfecf96Smrgstatic INLINE void rdiv_fr_bi(n_real*, mpi*); 3935dfecf96Smrgstatic int cmp_fr_bi(long, long, mpi*); 3945dfecf96Smrg 3955dfecf96Smrg/* fixratio fixratio */ 3965dfecf96Smrgstatic void rop_fr_fr_as_xr(n_real*, long, long, int); 3975dfecf96Smrgstatic void rop_fr_fr_md_xr(n_real*, long, long, int); 3985dfecf96Smrgstatic INLINE void radd_fr_fr(n_real*, long, long); 3995dfecf96Smrgstatic INLINE void rsub_fr_fr(n_real*, long, long); 4005dfecf96Smrgstatic INLINE void rmul_fr_fr(n_real*, long, long); 4015dfecf96Smrgstatic INLINE void rdiv_fr_fr(n_real*, long, long); 4025dfecf96Smrgstatic INLINE int cmp_fr_fr(long, long, long, long); 4035dfecf96Smrg 4045dfecf96Smrg/* fixratio bigratio */ 4055dfecf96Smrgstatic void rop_fr_br_asmd_xr(n_real*, mpr*, int); 4065dfecf96Smrgstatic INLINE void radd_fr_br(n_real*, mpr*); 4075dfecf96Smrgstatic INLINE void rsub_fr_br(n_real*, mpr*); 4085dfecf96Smrgstatic INLINE void rmul_fr_br(n_real*, mpr*); 4095dfecf96Smrgstatic INLINE void rdiv_fr_br(n_real*, mpr*); 4105dfecf96Smrgstatic int cmp_fr_br(long, long, mpr*); 4115dfecf96Smrg 4125dfecf96Smrg/* bigratio fixnum */ 4135dfecf96Smrgstatic void rop_br_fi_asmd_xr(n_real*, long, int); 4145dfecf96Smrgstatic INLINE void radd_br_fi(n_real*, long); 4155dfecf96Smrgstatic INLINE void rsub_br_fi(n_real*, long); 4165dfecf96Smrgstatic INLINE void rmul_br_fi(n_real*, long); 4175dfecf96Smrgstatic INLINE void rdiv_br_fi(n_real*, long); 4185dfecf96Smrgstatic int cmp_br_fi(mpr*, long); 4195dfecf96Smrg 4205dfecf96Smrg/* bigratio bignum */ 4215dfecf96Smrgstatic void rop_br_bi_as_xr(n_real*, mpi*, int); 4225dfecf96Smrgstatic INLINE void radd_br_bi(n_real*, mpi*); 4235dfecf96Smrgstatic INLINE void rsub_br_bi(n_real*, mpi*); 4245dfecf96Smrgstatic INLINE void rmul_br_bi(n_real*, mpi*); 4255dfecf96Smrgstatic INLINE void rdiv_br_bi(n_real*, mpi*); 4265dfecf96Smrgstatic int cmp_br_bi(mpr*, mpi*); 4275dfecf96Smrg 4285dfecf96Smrg/* bigratio fixratio */ 4295dfecf96Smrgstatic void rop_br_fr_asmd_xr(n_real*, long, long, int); 4305dfecf96Smrgstatic INLINE void radd_br_fr(n_real*, long, long); 4315dfecf96Smrgstatic INLINE void rsub_br_fr(n_real*, long, long); 4325dfecf96Smrgstatic INLINE void rmul_br_fr(n_real*, long, long); 4335dfecf96Smrgstatic INLINE void rdiv_br_fr(n_real*, long, long); 4345dfecf96Smrgstatic int cmp_br_fr(mpr*, long, long); 4355dfecf96Smrg 4365dfecf96Smrg/* bigratio bigratio */ 4375dfecf96Smrgstatic INLINE void radd_br_br(n_real*, mpr*); 4385dfecf96Smrgstatic INLINE void rsub_br_br(n_real*, mpr*); 4395dfecf96Smrgstatic INLINE void rmul_br_br(n_real*, mpr*); 4405dfecf96Smrgstatic INLINE void rdiv_br_br(n_real*, mpr*); 4415dfecf96Smrgstatic INLINE int cmp_br_br(mpr*, mpr*); 4425dfecf96Smrg 4435dfecf96Smrg/* 4445dfecf96Smrg * Initialization 4455dfecf96Smrg */ 4465dfecf96Smrgstatic n_real zero, one, two; 4475dfecf96Smrg 4485dfecf96Smrgstatic char *fatal_error_strings[] = { 4495dfecf96Smrg#define DIVIDE_BY_ZERO 0 4505dfecf96Smrg "divide by zero", 4515dfecf96Smrg#define FLOATING_POINT_OVERFLOW 1 4525dfecf96Smrg "floating point overflow", 4535dfecf96Smrg#define FLOATING_POINT_EXCEPTION 2 4545dfecf96Smrg "floating point exception" 4555dfecf96Smrg}; 4565dfecf96Smrg 4575dfecf96Smrgstatic char *fatal_object_error_strings[] = { 4585dfecf96Smrg#define NOT_A_NUMBER 0 4595dfecf96Smrg "is not a number", 4605dfecf96Smrg#define NOT_A_REAL_NUMBER 1 4615dfecf96Smrg "is not a real number", 4625dfecf96Smrg#define NOT_AN_INTEGER 2 4635dfecf96Smrg "is not an integer" 4645dfecf96Smrg}; 4655dfecf96Smrg 4665dfecf96Smrg/* 4675dfecf96Smrg * Implementation 4685dfecf96Smrg */ 4695dfecf96Smrgstatic void 4705dfecf96Smrgfatal_error(int num) 4715dfecf96Smrg{ 4725dfecf96Smrg LispDestroy(fatal_error_strings[num]); 4735dfecf96Smrg} 4745dfecf96Smrg 4755dfecf96Smrgstatic void 4765dfecf96Smrgfatal_object_error(LispObj *obj, int num) 4775dfecf96Smrg{ 4785dfecf96Smrg LispDestroy("%s %s", STROBJ(obj), fatal_object_error_strings[num]); 4795dfecf96Smrg} 4805dfecf96Smrg 4815dfecf96Smrgstatic void 4825dfecf96Smrgfatal_builtin_object_error(LispBuiltin *builtin, LispObj *obj, int num) 4835dfecf96Smrg{ 4845dfecf96Smrg LispDestroy("%s: %s %s", STRFUN(builtin), STROBJ(obj), 4855dfecf96Smrg fatal_object_error_strings[num]); 4865dfecf96Smrg} 4875dfecf96Smrg 4885dfecf96Smrgstatic void 4895dfecf96Smrgnumber_init(void) 4905dfecf96Smrg{ 4915dfecf96Smrg zero.type = one.type = two.type = N_FIXNUM; 4925dfecf96Smrg zero.data.fixnum = 0; 4935dfecf96Smrg one.data.fixnum = 1; 4945dfecf96Smrg two.data.fixnum = 2; 4955dfecf96Smrg} 4965dfecf96Smrg 4975dfecf96Smrgstatic double 4985dfecf96Smrgbi_getd(mpi *bignum) 4995dfecf96Smrg{ 5005dfecf96Smrg double value = mpi_getd(bignum); 5015dfecf96Smrg 5025dfecf96Smrg if (!finite(value)) 5035dfecf96Smrg fatal_error(FLOATING_POINT_EXCEPTION); 5045dfecf96Smrg 5055dfecf96Smrg return (value); 5065dfecf96Smrg} 5075dfecf96Smrg 5085dfecf96Smrgstatic double 5095dfecf96Smrgbr_getd(mpr *bigratio) 5105dfecf96Smrg{ 5115dfecf96Smrg double value = mpr_getd(bigratio); 5125dfecf96Smrg 5135dfecf96Smrg if (!finite(value)) 5145dfecf96Smrg fatal_error(FLOATING_POINT_EXCEPTION); 5155dfecf96Smrg 5165dfecf96Smrg return (value); 5175dfecf96Smrg} 5185dfecf96Smrg 5195dfecf96Smrgstatic LispObj * 5205dfecf96Smrgnumber_pi(void) 5215dfecf96Smrg{ 5225dfecf96Smrg LispObj *result; 5235dfecf96Smrg#ifndef M_PI 5245dfecf96Smrg#define M_PI 3.14159265358979323846 5255dfecf96Smrg#endif 5265dfecf96Smrg result = DFLOAT(M_PI); 5275dfecf96Smrg 5285dfecf96Smrg return (result); 5295dfecf96Smrg} 5305dfecf96Smrg 5315dfecf96Smrgstatic void 5325dfecf96Smrgset_real_real(n_real *real, n_real *val) 5335dfecf96Smrg{ 5345dfecf96Smrg switch (RTYPE(real) = RTYPE(val)) { 5355dfecf96Smrg case N_FIXNUM: 5365dfecf96Smrg RFI(real) = RFI(val); 5375dfecf96Smrg break; 5385dfecf96Smrg case N_BIGNUM: 5395dfecf96Smrg RBI(real) = XALLOC(mpi); 5405dfecf96Smrg mpi_init(RBI(real)); 5415dfecf96Smrg mpi_set(RBI(real), RBI(val)); 5425dfecf96Smrg break; 5435dfecf96Smrg case N_FLONUM: 5445dfecf96Smrg RFF(real) = RFF(val); 5455dfecf96Smrg break; 5465dfecf96Smrg case N_FIXRATIO: 5475dfecf96Smrg RFRN(real) = RFRN(val); 5485dfecf96Smrg RFRD(real) = RFRD(val); 5495dfecf96Smrg break; 5505dfecf96Smrg case N_BIGRATIO: 5515dfecf96Smrg RBR(real) = XALLOC(mpr); 5525dfecf96Smrg mpr_init(RBR(real)); 5535dfecf96Smrg mpr_set(RBR(real), RBR(val)); 5545dfecf96Smrg break; 5555dfecf96Smrg } 5565dfecf96Smrg} 5575dfecf96Smrg 5585dfecf96Smrgstatic void 5595dfecf96Smrgset_real_object(n_real *real, LispObj *obj) 5605dfecf96Smrg{ 5615dfecf96Smrg switch (OBJECT_TYPE(obj)) { 5625dfecf96Smrg case LispFixnum_t: 5635dfecf96Smrg RTYPE(real) = N_FIXNUM; 5645dfecf96Smrg RFI(real) = OFI(obj); 5655dfecf96Smrg break; 5665dfecf96Smrg case LispInteger_t: 5675dfecf96Smrg RTYPE(real) = N_FIXNUM; 5685dfecf96Smrg RFI(real) = OII(obj); 5695dfecf96Smrg break; 5705dfecf96Smrg case LispBignum_t: 5715dfecf96Smrg RTYPE(real) = N_BIGNUM; 5725dfecf96Smrg RBI(real) = XALLOC(mpi); 5735dfecf96Smrg mpi_init(RBI(real)); 5745dfecf96Smrg mpi_set(RBI(real), OBI(obj)); 5755dfecf96Smrg break; 5765dfecf96Smrg case LispDFloat_t: 5775dfecf96Smrg RTYPE(real) = N_FLONUM; 5785dfecf96Smrg RFF(real) = ODF(obj); 5795dfecf96Smrg break; 5805dfecf96Smrg case LispRatio_t: 5815dfecf96Smrg RTYPE(real) = N_FIXRATIO; 5825dfecf96Smrg RFRN(real) = OFRN(obj); 5835dfecf96Smrg RFRD(real) = OFRD(obj); 5845dfecf96Smrg break; 5855dfecf96Smrg case LispBigratio_t: 5865dfecf96Smrg RTYPE(real) = N_BIGRATIO; 5875dfecf96Smrg RBR(real) = XALLOC(mpr); 5885dfecf96Smrg mpr_init(RBR(real)); 5895dfecf96Smrg mpr_set(RBR(real), OBR(obj)); 5905dfecf96Smrg break; 5915dfecf96Smrg default: 5925dfecf96Smrg fatal_object_error(obj, NOT_A_REAL_NUMBER); 5935dfecf96Smrg break; 5945dfecf96Smrg } 5955dfecf96Smrg} 5965dfecf96Smrg 5975dfecf96Smrgstatic void 5985dfecf96Smrgset_number_object(n_number *num, LispObj *obj) 5995dfecf96Smrg{ 6005dfecf96Smrg switch (OBJECT_TYPE(obj)) { 6015dfecf96Smrg case LispFixnum_t: 6025dfecf96Smrg num->complex = 0; 6035dfecf96Smrg NRTYPE(num) = N_FIXNUM; 6045dfecf96Smrg NRFI(num) = OFI(obj); 6055dfecf96Smrg break; 6065dfecf96Smrg case LispInteger_t: 6075dfecf96Smrg num->complex = 0; 6085dfecf96Smrg NRTYPE(num) = N_FIXNUM; 6095dfecf96Smrg NRFI(num) = OII(obj); 6105dfecf96Smrg break; 6115dfecf96Smrg case LispBignum_t: 6125dfecf96Smrg num->complex = 0; 6135dfecf96Smrg NRTYPE(num) = N_BIGNUM; 6145dfecf96Smrg NRBI(num) = XALLOC(mpi); 6155dfecf96Smrg mpi_init(NRBI(num)); 6165dfecf96Smrg mpi_set(NRBI(num), OBI(obj)); 6175dfecf96Smrg break; 6185dfecf96Smrg case LispDFloat_t: 6195dfecf96Smrg num->complex = 0; 6205dfecf96Smrg NRTYPE(num) = N_FLONUM; 6215dfecf96Smrg NRFF(num) = ODF(obj); 6225dfecf96Smrg break; 6235dfecf96Smrg case LispRatio_t: 6245dfecf96Smrg num->complex = 0; 6255dfecf96Smrg NRTYPE(num) = N_FIXRATIO; 6265dfecf96Smrg NRFRN(num) = OFRN(obj); 6275dfecf96Smrg NRFRD(num) = OFRD(obj); 6285dfecf96Smrg break; 6295dfecf96Smrg case LispBigratio_t: 6305dfecf96Smrg num->complex = 0; 6315dfecf96Smrg NRTYPE(num) = N_BIGRATIO; 6325dfecf96Smrg NRBR(num) = XALLOC(mpr); 6335dfecf96Smrg mpr_init(NRBR(num)); 6345dfecf96Smrg mpr_set(NRBR(num), OBR(obj)); 6355dfecf96Smrg break; 6365dfecf96Smrg case LispComplex_t: 6375dfecf96Smrg num->complex = 1; 6385dfecf96Smrg set_real_object(NREAL(num), OCXR(obj)); 6395dfecf96Smrg set_real_object(NIMAG(num), OCXI(obj)); 6405dfecf96Smrg break; 6415dfecf96Smrg default: 6425dfecf96Smrg fatal_object_error(obj, NOT_A_NUMBER); 6435dfecf96Smrg break; 6445dfecf96Smrg } 6455dfecf96Smrg} 6465dfecf96Smrg 6475dfecf96Smrgstatic void 6485dfecf96Smrgclear_real(n_real *real) 6495dfecf96Smrg{ 6505dfecf96Smrg if (RTYPE(real) == N_BIGNUM) { 6515dfecf96Smrg mpi_clear(RBI(real)); 6525dfecf96Smrg XFREE(RBI(real)); 6535dfecf96Smrg } 6545dfecf96Smrg else if (RTYPE(real) == N_BIGRATIO) { 6555dfecf96Smrg mpr_clear(RBR(real)); 6565dfecf96Smrg XFREE(RBR(real)); 6575dfecf96Smrg } 6585dfecf96Smrg} 6595dfecf96Smrg 6605dfecf96Smrgstatic void 6615dfecf96Smrgclear_number(n_number *num) 6625dfecf96Smrg{ 6635dfecf96Smrg clear_real(NREAL(num)); 6645dfecf96Smrg if (num->complex) 6655dfecf96Smrg clear_real(NIMAG(num)); 6665dfecf96Smrg} 6675dfecf96Smrg 6685dfecf96Smrgstatic LispObj * 6695dfecf96Smrgmake_real_object(n_real *real) 6705dfecf96Smrg{ 6715dfecf96Smrg LispObj *obj; 6725dfecf96Smrg 6735dfecf96Smrg switch (RTYPE(real)) { 6745dfecf96Smrg case N_FIXNUM: 6755dfecf96Smrg if (RFI(real) > MOST_POSITIVE_FIXNUM || 6765dfecf96Smrg RFI(real) < MOST_NEGATIVE_FIXNUM) { 6775dfecf96Smrg obj = LispNew(NIL, NIL); 6785dfecf96Smrg obj->type = LispInteger_t; 6795dfecf96Smrg OII(obj) = RFI(real); 6805dfecf96Smrg } 6815dfecf96Smrg else 6825dfecf96Smrg obj = FIXNUM(RFI(real)); 6835dfecf96Smrg break; 6845dfecf96Smrg case N_BIGNUM: 6855dfecf96Smrg obj = BIGNUM(RBI(real)); 6865dfecf96Smrg break; 6875dfecf96Smrg case N_FLONUM: 6885dfecf96Smrg obj = DFLOAT(RFF(real)); 6895dfecf96Smrg break; 6905dfecf96Smrg case N_FIXRATIO: 6915dfecf96Smrg obj = LispNew(NIL, NIL); 6925dfecf96Smrg obj->type = LispRatio_t; 6935dfecf96Smrg OFRN(obj) = RFRN(real); 6945dfecf96Smrg OFRD(obj) = RFRD(real); 6955dfecf96Smrg break; 6965dfecf96Smrg case N_BIGRATIO: 6975dfecf96Smrg obj = BIGRATIO(RBR(real)); 6985dfecf96Smrg break; 6995dfecf96Smrg default: 7005dfecf96Smrg obj = NIL; 7015dfecf96Smrg break; 7025dfecf96Smrg } 7035dfecf96Smrg 7045dfecf96Smrg return (obj); 7055dfecf96Smrg} 7065dfecf96Smrg 7075dfecf96Smrgstatic LispObj * 7085dfecf96Smrgmake_number_object(n_number *num) 7095dfecf96Smrg{ 7105dfecf96Smrg LispObj *obj; 7115dfecf96Smrg 7125dfecf96Smrg if (num->complex) { 7135dfecf96Smrg GC_ENTER(); 7145dfecf96Smrg 7155dfecf96Smrg obj = LispNew(NIL, NIL); 7165dfecf96Smrg GC_PROTECT(obj); 7175dfecf96Smrg OCXI(obj) = NIL; 7185dfecf96Smrg obj->type = LispComplex_t; 7195dfecf96Smrg OCXR(obj) = make_real_object(NREAL(num)); 7205dfecf96Smrg OCXI(obj) = make_real_object(NIMAG(num)); 7215dfecf96Smrg GC_LEAVE(); 7225dfecf96Smrg } 7235dfecf96Smrg else { 7245dfecf96Smrg switch (NRTYPE(num)) { 7255dfecf96Smrg case N_FIXNUM: 7265dfecf96Smrg if (NRFI(num) > MOST_POSITIVE_FIXNUM || 7275dfecf96Smrg NRFI(num) < MOST_NEGATIVE_FIXNUM) { 7285dfecf96Smrg obj = LispNew(NIL, NIL); 7295dfecf96Smrg obj->type = LispInteger_t; 7305dfecf96Smrg OII(obj) = NRFI(num); 7315dfecf96Smrg } 7325dfecf96Smrg else 7335dfecf96Smrg obj = FIXNUM(NRFI(num)); 7345dfecf96Smrg break; 7355dfecf96Smrg case N_BIGNUM: 7365dfecf96Smrg obj = BIGNUM(NRBI(num)); 7375dfecf96Smrg break; 7385dfecf96Smrg case N_FLONUM: 7395dfecf96Smrg obj = DFLOAT(NRFF(num)); 7405dfecf96Smrg break; 7415dfecf96Smrg case N_FIXRATIO: 7425dfecf96Smrg obj = LispNew(NIL, NIL); 7435dfecf96Smrg obj->type = LispRatio_t; 7445dfecf96Smrg OFRN(obj) = NRFRN(num); 7455dfecf96Smrg OFRD(obj) = NRFRD(num); 7465dfecf96Smrg break; 7475dfecf96Smrg case N_BIGRATIO: 7485dfecf96Smrg obj = BIGRATIO(NRBR(num)); 7495dfecf96Smrg break; 7505dfecf96Smrg default: 7515dfecf96Smrg obj = NIL; 7525dfecf96Smrg break; 7535dfecf96Smrg } 7545dfecf96Smrg } 7555dfecf96Smrg 7565dfecf96Smrg return (obj); 7575dfecf96Smrg} 7585dfecf96Smrg 7595dfecf96Smrg#define DEFOP_REAL_REAL(OP) \ 7605dfecf96SmrgOP##_real_real(n_real *real, n_real *val) \ 7615dfecf96Smrg{ \ 7625dfecf96Smrg switch (RTYPE(real)) { \ 7635dfecf96Smrg case N_FIXNUM: \ 7645dfecf96Smrg switch (RTYPE(val)) { \ 7655dfecf96Smrg case N_FIXNUM: \ 7665dfecf96Smrg r##OP##_fi_fi(real, RFI(val)); \ 7675dfecf96Smrg break; \ 7685dfecf96Smrg case N_BIGNUM: \ 7695dfecf96Smrg r##OP##_fi_bi(real, RBI(val)); \ 7705dfecf96Smrg break; \ 7715dfecf96Smrg case N_FLONUM: \ 7725dfecf96Smrg r##OP##_flonum(real, (double)RFI(real), RFF(val)); \ 7735dfecf96Smrg break; \ 7745dfecf96Smrg case N_FIXRATIO: \ 7755dfecf96Smrg r##OP##_fi_fr(real, RFRN(val), RFRD(val)); \ 7765dfecf96Smrg break; \ 7775dfecf96Smrg case N_BIGRATIO: \ 7785dfecf96Smrg r##OP##_fi_br(real, RBR(val)); \ 7795dfecf96Smrg break; \ 7805dfecf96Smrg } \ 7815dfecf96Smrg break; \ 7825dfecf96Smrg case N_BIGNUM: \ 7835dfecf96Smrg switch (RTYPE(val)) { \ 7845dfecf96Smrg case N_FIXNUM: \ 7855dfecf96Smrg r##OP##_bi_fi(real, RFI(val)); \ 7865dfecf96Smrg break; \ 7875dfecf96Smrg case N_BIGNUM: \ 7885dfecf96Smrg r##OP##_bi_bi(real, RBI(val)); \ 7895dfecf96Smrg break; \ 7905dfecf96Smrg case N_FLONUM: \ 7915dfecf96Smrg r##OP##_flonum(real, bi_getd(RBI(real)), RFF(val)); \ 7925dfecf96Smrg break; \ 7935dfecf96Smrg case N_FIXRATIO: \ 7945dfecf96Smrg r##OP##_bi_fr(real, RFRN(val), RFRD(val)); \ 7955dfecf96Smrg break; \ 7965dfecf96Smrg case N_BIGRATIO: \ 7975dfecf96Smrg r##OP##_bi_br(real, RBR(val)); \ 7985dfecf96Smrg break; \ 7995dfecf96Smrg } \ 8005dfecf96Smrg break; \ 8015dfecf96Smrg case N_FLONUM: \ 8025dfecf96Smrg switch (RTYPE(val)) { \ 8035dfecf96Smrg case N_FIXNUM: \ 8045dfecf96Smrg r##OP##_flonum(real, RFF(real), (double)RFI(val)); \ 8055dfecf96Smrg break; \ 8065dfecf96Smrg case N_BIGNUM: \ 8075dfecf96Smrg r##OP##_flonum(real, RFF(real), bi_getd(RBI(val))); \ 8085dfecf96Smrg break; \ 8095dfecf96Smrg case N_FLONUM: \ 8105dfecf96Smrg r##OP##_flonum(real, RFF(real), RFF(val)); \ 8115dfecf96Smrg break; \ 8125dfecf96Smrg case N_FIXRATIO: \ 8135dfecf96Smrg r##OP##_flonum(real, RFF(real), \ 8145dfecf96Smrg (double)RFRN(val) / (double)RFRD(val));\ 8155dfecf96Smrg break; \ 8165dfecf96Smrg case N_BIGRATIO: \ 8175dfecf96Smrg r##OP##_flonum(real, RFF(real), br_getd(RBR(val))); \ 8185dfecf96Smrg break; \ 8195dfecf96Smrg } \ 8205dfecf96Smrg break; \ 8215dfecf96Smrg case N_FIXRATIO: \ 8225dfecf96Smrg switch (RTYPE(val)) { \ 8235dfecf96Smrg case N_FIXNUM: \ 8245dfecf96Smrg r##OP##_fr_fi(real, RFI(val)); \ 8255dfecf96Smrg break; \ 8265dfecf96Smrg case N_BIGNUM: \ 8275dfecf96Smrg r##OP##_fr_bi(real, RBI(val)); \ 8285dfecf96Smrg break; \ 8295dfecf96Smrg case N_FLONUM: \ 8305dfecf96Smrg r##OP##_flonum(real, \ 8315dfecf96Smrg (double)RFRN(real) / (double)RFRD(real),\ 8325dfecf96Smrg RFF(val)); \ 8335dfecf96Smrg break; \ 8345dfecf96Smrg case N_FIXRATIO: \ 8355dfecf96Smrg r##OP##_fr_fr(real, RFRN(val), RFRD(val)); \ 8365dfecf96Smrg break; \ 8375dfecf96Smrg case N_BIGRATIO: \ 8385dfecf96Smrg r##OP##_fr_br(real, RBR(val)); \ 8395dfecf96Smrg break; \ 8405dfecf96Smrg } \ 8415dfecf96Smrg break; \ 8425dfecf96Smrg case N_BIGRATIO: \ 8435dfecf96Smrg switch (RTYPE(val)) { \ 8445dfecf96Smrg case N_FIXNUM: \ 8455dfecf96Smrg r##OP##_br_fi(real, RFI(val)); \ 8465dfecf96Smrg break; \ 8475dfecf96Smrg case N_BIGNUM: \ 8485dfecf96Smrg r##OP##_br_bi(real, RBI(val)); \ 8495dfecf96Smrg break; \ 8505dfecf96Smrg case N_FLONUM: \ 8515dfecf96Smrg r##OP##_flonum(real, br_getd(RBR(real)), RFF(val)); \ 8525dfecf96Smrg break; \ 8535dfecf96Smrg case N_FIXRATIO: \ 8545dfecf96Smrg r##OP##_br_fr(real, RFRN(val), RFRD(val)); \ 8555dfecf96Smrg break; \ 8565dfecf96Smrg case N_BIGRATIO: \ 8575dfecf96Smrg r##OP##_br_br(real, RBR(val)); \ 8585dfecf96Smrg break; \ 8595dfecf96Smrg } \ 8605dfecf96Smrg break; \ 8615dfecf96Smrg } \ 8625dfecf96Smrg} 8635dfecf96Smrg 8645dfecf96Smrgstatic void 8655dfecf96SmrgDEFOP_REAL_REAL(add) 8665dfecf96Smrg 8675dfecf96Smrgstatic void 8685dfecf96SmrgDEFOP_REAL_REAL(sub) 8695dfecf96Smrg 8705dfecf96Smrgstatic void 8715dfecf96SmrgDEFOP_REAL_REAL(div) 8725dfecf96Smrg 8735dfecf96Smrgstatic void 8745dfecf96SmrgDEFOP_REAL_REAL(mul) 8755dfecf96Smrg 8765dfecf96Smrg 8775dfecf96Smrg#define DEFOP_REAL_OBJECT(OP) \ 8785dfecf96SmrgOP##_real_object(n_real *real, LispObj *obj) \ 8795dfecf96Smrg{ \ 8805dfecf96Smrg switch (OBJECT_TYPE(obj)) { \ 8815dfecf96Smrg case LispFixnum_t: \ 8825dfecf96Smrg switch (RTYPE(real)) { \ 8835dfecf96Smrg case N_FIXNUM: \ 8845dfecf96Smrg r##OP##_fi_fi(real, OFI(obj)); \ 8855dfecf96Smrg break; \ 8865dfecf96Smrg case N_BIGNUM: \ 8875dfecf96Smrg r##OP##_bi_fi(real, OFI(obj)); \ 8885dfecf96Smrg break; \ 8895dfecf96Smrg case N_FLONUM: \ 8905dfecf96Smrg r##OP##_flonum(real, RFF(real), (double)OFI(obj)); \ 8915dfecf96Smrg break; \ 8925dfecf96Smrg case N_FIXRATIO: \ 8935dfecf96Smrg r##OP##_fr_fi(real, OFI(obj)); \ 8945dfecf96Smrg break; \ 8955dfecf96Smrg case N_BIGRATIO: \ 8965dfecf96Smrg r##OP##_br_fi(real, OFI(obj)); \ 8975dfecf96Smrg break; \ 8985dfecf96Smrg } \ 8995dfecf96Smrg break; \ 9005dfecf96Smrg case LispInteger_t: \ 9015dfecf96Smrg switch (RTYPE(real)) { \ 9025dfecf96Smrg case N_FIXNUM: \ 9035dfecf96Smrg r##OP##_fi_fi(real, OII(obj)); \ 9045dfecf96Smrg break; \ 9055dfecf96Smrg case N_BIGNUM: \ 9065dfecf96Smrg r##OP##_bi_fi(real, OII(obj)); \ 9075dfecf96Smrg break; \ 9085dfecf96Smrg case N_FLONUM: \ 9095dfecf96Smrg r##OP##_flonum(real, RFF(real), (double)OII(obj)); \ 9105dfecf96Smrg break; \ 9115dfecf96Smrg case N_FIXRATIO: \ 9125dfecf96Smrg r##OP##_fr_fi(real, OII(obj)); \ 9135dfecf96Smrg break; \ 9145dfecf96Smrg case N_BIGRATIO: \ 9155dfecf96Smrg r##OP##_br_fi(real, OII(obj)); \ 9165dfecf96Smrg break; \ 9175dfecf96Smrg } \ 9185dfecf96Smrg break; \ 9195dfecf96Smrg case LispBignum_t: \ 9205dfecf96Smrg switch (RTYPE(real)) { \ 9215dfecf96Smrg case N_FIXNUM: \ 9225dfecf96Smrg r##OP##_fi_bi(real, OBI(obj)); \ 9235dfecf96Smrg break; \ 9245dfecf96Smrg case N_BIGNUM: \ 9255dfecf96Smrg r##OP##_bi_bi(real, OBI(obj)); \ 9265dfecf96Smrg break; \ 9275dfecf96Smrg case N_FLONUM: \ 9285dfecf96Smrg r##OP##_flonum(real, RFF(real), bi_getd(OBI(obj))); \ 9295dfecf96Smrg break; \ 9305dfecf96Smrg case N_FIXRATIO: \ 9315dfecf96Smrg r##OP##_fr_bi(real, OBI(obj)); \ 9325dfecf96Smrg break; \ 9335dfecf96Smrg case N_BIGRATIO: \ 9345dfecf96Smrg r##OP##_br_bi(real, OBI(obj)); \ 9355dfecf96Smrg break; \ 9365dfecf96Smrg } \ 9375dfecf96Smrg break; \ 9385dfecf96Smrg case LispDFloat_t: \ 9395dfecf96Smrg switch (RTYPE(real)) { \ 9405dfecf96Smrg case N_FIXNUM: \ 9415dfecf96Smrg r##OP##_flonum(real, (double)RFI(real), ODF(obj)); \ 9425dfecf96Smrg break; \ 9435dfecf96Smrg case N_BIGNUM: \ 9445dfecf96Smrg r##OP##_flonum(real, bi_getd(RBI(real)), ODF(obj)); \ 9455dfecf96Smrg break; \ 9465dfecf96Smrg case N_FLONUM: \ 9475dfecf96Smrg r##OP##_flonum(real, RFF(real), ODF(obj)); \ 9485dfecf96Smrg break; \ 9495dfecf96Smrg case N_FIXRATIO: \ 9505dfecf96Smrg r##OP##_flonum(real, \ 9515dfecf96Smrg (double)RFRN(real) / (double)RFRD(real),\ 9525dfecf96Smrg ODF(obj)); \ 9535dfecf96Smrg break; \ 9545dfecf96Smrg case N_BIGRATIO: \ 9555dfecf96Smrg r##OP##_flonum(real, br_getd(RBR(real)), ODF(obj)); \ 9565dfecf96Smrg break; \ 9575dfecf96Smrg } \ 9585dfecf96Smrg break; \ 9595dfecf96Smrg case LispRatio_t: \ 9605dfecf96Smrg switch (RTYPE(real)) { \ 9615dfecf96Smrg case N_FIXNUM: \ 9625dfecf96Smrg r##OP##_fi_fr(real, OFRN(obj), OFRD(obj)); \ 9635dfecf96Smrg break; \ 9645dfecf96Smrg case N_BIGNUM: \ 9655dfecf96Smrg r##OP##_bi_fr(real, OFRN(obj), OFRD(obj)); \ 9665dfecf96Smrg break; \ 9675dfecf96Smrg case N_FLONUM: \ 9685dfecf96Smrg r##OP##_flonum(real, RFF(real), \ 9695dfecf96Smrg (double)OFRN(obj) / (double)OFRD(obj)); \ 9705dfecf96Smrg break; \ 9715dfecf96Smrg case N_FIXRATIO: \ 9725dfecf96Smrg r##OP##_fr_fr(real, OFRN(obj), OFRD(obj)); \ 9735dfecf96Smrg break; \ 9745dfecf96Smrg case N_BIGRATIO: \ 9755dfecf96Smrg r##OP##_br_fr(real, OFRN(obj), OFRD(obj)); \ 9765dfecf96Smrg break; \ 9775dfecf96Smrg } \ 9785dfecf96Smrg break; \ 9795dfecf96Smrg case LispBigratio_t: \ 9805dfecf96Smrg switch (RTYPE(real)) { \ 9815dfecf96Smrg case N_FIXNUM: \ 9825dfecf96Smrg r##OP##_fi_br(real, OBR(obj)); \ 9835dfecf96Smrg break; \ 9845dfecf96Smrg case N_BIGNUM: \ 9855dfecf96Smrg r##OP##_bi_br(real, OBR(obj)); \ 9865dfecf96Smrg break; \ 9875dfecf96Smrg case N_FLONUM: \ 9885dfecf96Smrg r##OP##_flonum(real, RFF(real), br_getd(OBR(obj))); \ 9895dfecf96Smrg break; \ 9905dfecf96Smrg case N_FIXRATIO: \ 9915dfecf96Smrg r##OP##_fr_br(real, OBR(obj)); \ 9925dfecf96Smrg break; \ 9935dfecf96Smrg case N_BIGRATIO: \ 9945dfecf96Smrg r##OP##_br_br(real, OBR(obj)); \ 9955dfecf96Smrg break; \ 9965dfecf96Smrg } \ 9975dfecf96Smrg break; \ 9985dfecf96Smrg default: \ 9995dfecf96Smrg fatal_object_error(obj, NOT_A_REAL_NUMBER); \ 10005dfecf96Smrg break; \ 10015dfecf96Smrg } \ 10025dfecf96Smrg} 10035dfecf96Smrg 10045dfecf96Smrgstatic void 10055dfecf96SmrgDEFOP_REAL_OBJECT(add) 10065dfecf96Smrg 10075dfecf96Smrgstatic void 10085dfecf96SmrgDEFOP_REAL_OBJECT(sub) 10095dfecf96Smrg 10105dfecf96Smrgstatic void 10115dfecf96SmrgDEFOP_REAL_OBJECT(div) 10125dfecf96Smrg 10135dfecf96Smrgstatic void 10145dfecf96SmrgDEFOP_REAL_OBJECT(mul) 10155dfecf96Smrg 10165dfecf96Smrg 10175dfecf96Smrg#define DEFOP_NUMBER_OBJECT(OP) \ 10185dfecf96SmrgOP##_number_object(n_number *num, LispObj *obj) \ 10195dfecf96Smrg{ \ 10205dfecf96Smrg if (num->complex) { \ 10215dfecf96Smrg switch (OBJECT_TYPE(obj)) { \ 10225dfecf96Smrg case LispFixnum_t: \ 10235dfecf96Smrg case LispInteger_t: \ 10245dfecf96Smrg case LispBignum_t: \ 10255dfecf96Smrg case LispDFloat_t: \ 10265dfecf96Smrg case LispRatio_t: \ 10275dfecf96Smrg case LispBigratio_t: \ 10285dfecf96Smrg n##OP##_cx_re(num, obj); \ 10295dfecf96Smrg break; \ 10305dfecf96Smrg case LispComplex_t: \ 10315dfecf96Smrg n##OP##_cx_cx(num, obj); \ 10325dfecf96Smrg break; \ 10335dfecf96Smrg default: \ 10345dfecf96Smrg fatal_object_error(obj, NOT_A_NUMBER); \ 10355dfecf96Smrg break; \ 10365dfecf96Smrg } \ 10375dfecf96Smrg } \ 10385dfecf96Smrg else { \ 10395dfecf96Smrg switch (OBJECT_TYPE(obj)) { \ 10405dfecf96Smrg case LispFixnum_t: \ 10415dfecf96Smrg switch (NRTYPE(num)) { \ 10425dfecf96Smrg case N_FIXNUM: \ 10435dfecf96Smrg r##OP##_fi_fi(NREAL(num), OFI(obj)); \ 10445dfecf96Smrg break; \ 10455dfecf96Smrg case N_BIGNUM: \ 10465dfecf96Smrg r##OP##_bi_fi(NREAL(num), OFI(obj)); \ 10475dfecf96Smrg break; \ 10485dfecf96Smrg case N_FLONUM: \ 10495dfecf96Smrg r##OP##_flonum(NREAL(num), NRFF(num), \ 10505dfecf96Smrg (double)OFI(obj)); \ 10515dfecf96Smrg break; \ 10525dfecf96Smrg case N_FIXRATIO: \ 10535dfecf96Smrg r##OP##_fr_fi(NREAL(num), OFI(obj)); \ 10545dfecf96Smrg break; \ 10555dfecf96Smrg case N_BIGRATIO: \ 10565dfecf96Smrg r##OP##_br_fi(NREAL(num), OFI(obj)); \ 10575dfecf96Smrg break; \ 10585dfecf96Smrg } \ 10595dfecf96Smrg break; \ 10605dfecf96Smrg case LispInteger_t: \ 10615dfecf96Smrg switch (NRTYPE(num)) { \ 10625dfecf96Smrg case N_FIXNUM: \ 10635dfecf96Smrg r##OP##_fi_fi(NREAL(num), OII(obj)); \ 10645dfecf96Smrg break; \ 10655dfecf96Smrg case N_BIGNUM: \ 10665dfecf96Smrg r##OP##_bi_fi(NREAL(num), OII(obj)); \ 10675dfecf96Smrg break; \ 10685dfecf96Smrg case N_FLONUM: \ 10695dfecf96Smrg r##OP##_flonum(NREAL(num), NRFF(num), \ 10705dfecf96Smrg (double)OII(obj)); \ 10715dfecf96Smrg break; \ 10725dfecf96Smrg case N_FIXRATIO: \ 10735dfecf96Smrg r##OP##_fr_fi(NREAL(num), OII(obj)); \ 10745dfecf96Smrg break; \ 10755dfecf96Smrg case N_BIGRATIO: \ 10765dfecf96Smrg r##OP##_br_fi(NREAL(num), OII(obj)); \ 10775dfecf96Smrg break; \ 10785dfecf96Smrg } \ 10795dfecf96Smrg break; \ 10805dfecf96Smrg case LispBignum_t: \ 10815dfecf96Smrg switch (NRTYPE(num)) { \ 10825dfecf96Smrg case N_FIXNUM: \ 10835dfecf96Smrg r##OP##_fi_bi(NREAL(num), OBI(obj)); \ 10845dfecf96Smrg break; \ 10855dfecf96Smrg case N_BIGNUM: \ 10865dfecf96Smrg r##OP##_bi_bi(NREAL(num), OBI(obj)); \ 10875dfecf96Smrg break; \ 10885dfecf96Smrg case N_FLONUM: \ 10895dfecf96Smrg r##OP##_flonum(NREAL(num), NRFF(num), \ 10905dfecf96Smrg bi_getd(OBI(obj))); \ 10915dfecf96Smrg break; \ 10925dfecf96Smrg case N_FIXRATIO: \ 10935dfecf96Smrg r##OP##_fr_bi(NREAL(num), OBI(obj)); \ 10945dfecf96Smrg break; \ 10955dfecf96Smrg case N_BIGRATIO: \ 10965dfecf96Smrg r##OP##_br_bi(NREAL(num), OBI(obj)); \ 10975dfecf96Smrg break; \ 10985dfecf96Smrg } \ 10995dfecf96Smrg break; \ 11005dfecf96Smrg case LispDFloat_t: \ 11015dfecf96Smrg switch (NRTYPE(num)) { \ 11025dfecf96Smrg case N_FIXNUM: \ 11035dfecf96Smrg r##OP##_flonum(NREAL(num), (double)NRFI(num), \ 11045dfecf96Smrg ODF(obj)); \ 11055dfecf96Smrg break; \ 11065dfecf96Smrg case N_BIGNUM: \ 11075dfecf96Smrg r##OP##_flonum(NREAL(num), bi_getd(NRBI(num)), \ 11085dfecf96Smrg ODF(obj)); \ 11095dfecf96Smrg break; \ 11105dfecf96Smrg case N_FLONUM: \ 11115dfecf96Smrg r##OP##_flonum(NREAL(num), NRFF(num), ODF(obj));\ 11125dfecf96Smrg break; \ 11135dfecf96Smrg case N_FIXRATIO: \ 11145dfecf96Smrg r##OP##_flonum(NREAL(num), \ 11155dfecf96Smrg (double)NRFRN(num) / \ 11165dfecf96Smrg (double)NRFRD(num), \ 11175dfecf96Smrg ODF(obj)); \ 11185dfecf96Smrg break; \ 11195dfecf96Smrg case N_BIGRATIO: \ 11205dfecf96Smrg r##OP##_flonum(NREAL(num), br_getd(NRBR(num)), \ 11215dfecf96Smrg ODF(obj)); \ 11225dfecf96Smrg break; \ 11235dfecf96Smrg } \ 11245dfecf96Smrg break; \ 11255dfecf96Smrg case LispRatio_t: \ 11265dfecf96Smrg switch (NRTYPE(num)) { \ 11275dfecf96Smrg case N_FIXNUM: \ 11285dfecf96Smrg r##OP##_fi_fr(NREAL(num), OFRN(obj), OFRD(obj));\ 11295dfecf96Smrg break; \ 11305dfecf96Smrg case N_BIGNUM: \ 11315dfecf96Smrg r##OP##_bi_fr(NREAL(num), OFRN(obj), OFRD(obj));\ 11325dfecf96Smrg break; \ 11335dfecf96Smrg case N_FLONUM: \ 11345dfecf96Smrg r##OP##_flonum(NREAL(num), NRFF(num), \ 11355dfecf96Smrg (double)OFRN(obj) / \ 11365dfecf96Smrg (double)OFRD(obj)); \ 11375dfecf96Smrg break; \ 11385dfecf96Smrg case N_FIXRATIO: \ 11395dfecf96Smrg r##OP##_fr_fr(NREAL(num), OFRN(obj), OFRD(obj));\ 11405dfecf96Smrg break; \ 11415dfecf96Smrg case N_BIGRATIO: \ 11425dfecf96Smrg r##OP##_br_fr(NREAL(num), OFRN(obj), OFRD(obj));\ 11435dfecf96Smrg break; \ 11445dfecf96Smrg } \ 11455dfecf96Smrg break; \ 11465dfecf96Smrg case LispBigratio_t: \ 11475dfecf96Smrg switch (NRTYPE(num)) { \ 11485dfecf96Smrg case N_FIXNUM: \ 11495dfecf96Smrg r##OP##_fi_br(NREAL(num), OBR(obj)); \ 11505dfecf96Smrg break; \ 11515dfecf96Smrg case N_BIGNUM: \ 11525dfecf96Smrg r##OP##_bi_br(NREAL(num), OBR(obj)); \ 11535dfecf96Smrg break; \ 11545dfecf96Smrg case N_FLONUM: \ 11555dfecf96Smrg r##OP##_flonum(NREAL(num), NRFF(num), \ 11565dfecf96Smrg br_getd(OBR(obj))); \ 11575dfecf96Smrg break; \ 11585dfecf96Smrg case N_FIXRATIO: \ 11595dfecf96Smrg r##OP##_fr_br(NREAL(num), OBR(obj)); \ 11605dfecf96Smrg break; \ 11615dfecf96Smrg case N_BIGRATIO: \ 11625dfecf96Smrg r##OP##_br_br(NREAL(num), OBR(obj)); \ 11635dfecf96Smrg break; \ 11645dfecf96Smrg } \ 11655dfecf96Smrg break; \ 11665dfecf96Smrg case LispComplex_t: \ 11675dfecf96Smrg n##OP##_re_cx(num, obj); \ 11685dfecf96Smrg break; \ 11695dfecf96Smrg default: \ 11705dfecf96Smrg fatal_object_error(obj, NOT_A_NUMBER); \ 11715dfecf96Smrg break; \ 11725dfecf96Smrg } \ 11735dfecf96Smrg } \ 11745dfecf96Smrg} 11755dfecf96Smrg 11765dfecf96Smrgstatic void 11775dfecf96SmrgDEFOP_NUMBER_OBJECT(add) 11785dfecf96Smrg 11795dfecf96Smrgstatic void 11805dfecf96SmrgDEFOP_NUMBER_OBJECT(sub) 11815dfecf96Smrg 11825dfecf96Smrgstatic void 11835dfecf96SmrgDEFOP_NUMBER_OBJECT(div) 11845dfecf96Smrg 11855dfecf96Smrgstatic void 11865dfecf96SmrgDEFOP_NUMBER_OBJECT(mul) 11875dfecf96Smrg 11885dfecf96Smrg 11895dfecf96Smrg/************************************************************************ 11905dfecf96Smrg * ABS 11915dfecf96Smrg ************************************************************************/ 11925dfecf96Smrgstatic void 11935dfecf96Smrgabs_real(n_real *real) 11945dfecf96Smrg{ 11955dfecf96Smrg switch (RTYPE(real)) { 11965dfecf96Smrg case N_FIXNUM: rabs_fi(real); break; 11975dfecf96Smrg case N_BIGNUM: rabs_bi(real); break; 11985dfecf96Smrg case N_FLONUM: rabs_ff(real); break; 11995dfecf96Smrg case N_FIXRATIO: rabs_fr(real); break; 12005dfecf96Smrg case N_BIGRATIO: rabs_br(real); break; 12015dfecf96Smrg } 12025dfecf96Smrg} 12035dfecf96Smrg 12045dfecf96Smrgstatic void 12055dfecf96Smrgabs_number(n_number *num) 12065dfecf96Smrg{ 12075dfecf96Smrg if (num->complex) 12085dfecf96Smrg nabs_cx(num); 12095dfecf96Smrg else { 12105dfecf96Smrg switch (NRTYPE(num)) { 12115dfecf96Smrg case N_FIXNUM: rabs_fi(NREAL(num)); break; 12125dfecf96Smrg case N_BIGNUM: rabs_bi(NREAL(num)); break; 12135dfecf96Smrg case N_FLONUM: rabs_ff(NREAL(num)); break; 12145dfecf96Smrg case N_FIXRATIO: rabs_fr(NREAL(num)); break; 12155dfecf96Smrg case N_BIGRATIO: rabs_br(NREAL(num)); break; 12165dfecf96Smrg } 12175dfecf96Smrg } 12185dfecf96Smrg} 12195dfecf96Smrg 12205dfecf96Smrgstatic void 12215dfecf96Smrgnabs_cx(n_number *num) 12225dfecf96Smrg{ 12235dfecf96Smrg n_real temp; 12245dfecf96Smrg 12255dfecf96Smrg abs_real(NREAL(num)); 12265dfecf96Smrg abs_real(NIMAG(num)); 12275dfecf96Smrg 12285dfecf96Smrg if (cmp_real_real(NREAL(num), NIMAG(num)) < 0) { 12295dfecf96Smrg memcpy(&temp, NIMAG(num), sizeof(n_real)); 12305dfecf96Smrg memcpy(NIMAG(num), NREAL(num), sizeof(n_real)); 12315dfecf96Smrg memcpy(NREAL(num), &temp, sizeof(n_real)); 12325dfecf96Smrg } 12335dfecf96Smrg 12345dfecf96Smrg if (cmp_real_real(NIMAG(num), &zero) == 0) { 12355dfecf96Smrg num->complex = 0; 12365dfecf96Smrg if (NITYPE(num) == N_FLONUM) { 12375dfecf96Smrg /* change number type */ 12385dfecf96Smrg temp.type = N_FLONUM; 12395dfecf96Smrg temp.data.flonum = 1.0; 12405dfecf96Smrg mul_real_real(NREAL(num), &temp); 12415dfecf96Smrg } 12425dfecf96Smrg else 12435dfecf96Smrg clear_real(NIMAG(num)); 12445dfecf96Smrg } 12455dfecf96Smrg else { 12465dfecf96Smrg div_real_real(NIMAG(num), NREAL(num)); 12475dfecf96Smrg set_real_real(&temp, NIMAG(num)); 12485dfecf96Smrg mul_real_real(NIMAG(num), &temp); 12495dfecf96Smrg clear_real(&temp); 12505dfecf96Smrg 12515dfecf96Smrg add_real_real(NIMAG(num), &one); 12525dfecf96Smrg sqrt_real(NIMAG(num)); 12535dfecf96Smrg 12545dfecf96Smrg mul_real_real(NIMAG(num), NREAL(num)); 12555dfecf96Smrg clear_real(NREAL(num)); 12565dfecf96Smrg memcpy(NREAL(num), NIMAG(num), sizeof(n_real)); 12575dfecf96Smrg num->complex = 0; 12585dfecf96Smrg } 12595dfecf96Smrg} 12605dfecf96Smrg 12615dfecf96Smrgstatic INLINE void 12625dfecf96Smrgrabs_fi(n_real *real) 12635dfecf96Smrg{ 12645dfecf96Smrg if (RFI(real) < 0) 12655dfecf96Smrg rneg_fi(real); 12665dfecf96Smrg} 12675dfecf96Smrg 12685dfecf96Smrgstatic INLINE void 12695dfecf96Smrgrabs_bi(n_real *real) 12705dfecf96Smrg{ 12715dfecf96Smrg if (mpi_cmpi(RBI(real), 0) < 0) 12725dfecf96Smrg mpi_neg(RBI(real), RBI(real)); 12735dfecf96Smrg} 12745dfecf96Smrg 12755dfecf96Smrgstatic INLINE void 12765dfecf96Smrgrabs_ff(n_real *real) 12775dfecf96Smrg{ 12785dfecf96Smrg if (RFF(real) < 0.0) 12795dfecf96Smrg RFF(real) = -RFF(real); 12805dfecf96Smrg} 12815dfecf96Smrg 12825dfecf96Smrgstatic INLINE void 12835dfecf96Smrgrabs_fr(n_real *real) 12845dfecf96Smrg{ 12855dfecf96Smrg if (RFRN(real) < 0) 12865dfecf96Smrg rneg_fr(real); 12875dfecf96Smrg} 12885dfecf96Smrg 12895dfecf96Smrgstatic INLINE void 12905dfecf96Smrgrabs_br(n_real *real) 12915dfecf96Smrg{ 12925dfecf96Smrg if (mpi_cmpi(RBRN(real), 0) < 0) 12935dfecf96Smrg mpi_neg(RBRN(real), RBRN(real)); 12945dfecf96Smrg} 12955dfecf96Smrg 12965dfecf96Smrg 12975dfecf96Smrg/************************************************************************ 12985dfecf96Smrg * NEG 12995dfecf96Smrg ************************************************************************/ 13005dfecf96Smrgstatic void 13015dfecf96Smrgneg_real(n_real *real) 13025dfecf96Smrg{ 13035dfecf96Smrg switch (RTYPE(real)) { 13045dfecf96Smrg case N_FIXNUM: rneg_fi(real); break; 13055dfecf96Smrg case N_BIGNUM: rneg_bi(real); break; 13065dfecf96Smrg case N_FLONUM: rneg_ff(real); break; 13075dfecf96Smrg case N_FIXRATIO: rneg_fr(real); break; 13085dfecf96Smrg case N_BIGRATIO: rneg_br(real); break; 13095dfecf96Smrg } 13105dfecf96Smrg} 13115dfecf96Smrg 13125dfecf96Smrgstatic void 13135dfecf96Smrgneg_number(n_number *num) 13145dfecf96Smrg{ 13155dfecf96Smrg if (num->complex) { 13165dfecf96Smrg neg_real(NREAL(num)); 13175dfecf96Smrg neg_real(NIMAG(num)); 13185dfecf96Smrg } 13195dfecf96Smrg else { 13205dfecf96Smrg switch (NRTYPE(num)) { 13215dfecf96Smrg case N_FIXNUM: rneg_fi(NREAL(num)); break; 13225dfecf96Smrg case N_BIGNUM: rneg_bi(NREAL(num)); break; 13235dfecf96Smrg case N_FLONUM: rneg_ff(NREAL(num)); break; 13245dfecf96Smrg case N_FIXRATIO: rneg_fr(NREAL(num)); break; 13255dfecf96Smrg case N_BIGRATIO: rneg_br(NREAL(num)); break; 13265dfecf96Smrg } 13275dfecf96Smrg } 13285dfecf96Smrg} 13295dfecf96Smrg 13305dfecf96Smrgstatic void 13315dfecf96Smrgrneg_fi(n_real *real) 13325dfecf96Smrg{ 13335dfecf96Smrg if (RFI(real) == MINSLONG) { 13345dfecf96Smrg mpi *bigi = XALLOC(mpi); 13355dfecf96Smrg 13365dfecf96Smrg mpi_init(bigi); 13375dfecf96Smrg mpi_seti(bigi, RFI(real)); 13385dfecf96Smrg mpi_neg(bigi, bigi); 13395dfecf96Smrg RTYPE(real) = N_BIGNUM; 13405dfecf96Smrg RBI(real) = bigi; 13415dfecf96Smrg } 13425dfecf96Smrg else 13435dfecf96Smrg RFI(real) = -RFI(real); 13445dfecf96Smrg} 13455dfecf96Smrg 13465dfecf96Smrgstatic INLINE void 13475dfecf96Smrgrneg_bi(n_real *real) 13485dfecf96Smrg{ 13495dfecf96Smrg mpi_neg(RBI(real), RBI(real)); 13505dfecf96Smrg} 13515dfecf96Smrg 13525dfecf96Smrgstatic INLINE void 13535dfecf96Smrgrneg_ff(n_real *real) 13545dfecf96Smrg{ 13555dfecf96Smrg RFF(real) = -RFF(real); 13565dfecf96Smrg} 13575dfecf96Smrg 13585dfecf96Smrgstatic void 13595dfecf96Smrgrneg_fr(n_real *real) 13605dfecf96Smrg{ 13615dfecf96Smrg if (RFRN(real) == MINSLONG) { 13625dfecf96Smrg mpr *bigr = XALLOC(mpr); 13635dfecf96Smrg 13645dfecf96Smrg mpr_init(bigr); 13655dfecf96Smrg mpr_seti(bigr, RFRN(real), RFRD(real)); 13665dfecf96Smrg mpi_neg(mpr_num(bigr), mpr_num(bigr)); 13675dfecf96Smrg RTYPE(real) = N_BIGRATIO; 13685dfecf96Smrg RBR(real) = bigr; 13695dfecf96Smrg } 13705dfecf96Smrg else 13715dfecf96Smrg RFRN(real) = -RFRN(real); 13725dfecf96Smrg} 13735dfecf96Smrg 13745dfecf96Smrgstatic INLINE void 13755dfecf96Smrgrneg_br(n_real *real) 13765dfecf96Smrg{ 13775dfecf96Smrg mpi_neg(RBRN(real), RBRN(real)); 13785dfecf96Smrg} 13795dfecf96Smrg 13805dfecf96Smrg 13815dfecf96Smrg/************************************************************************ 13825dfecf96Smrg * SQRT 13835dfecf96Smrg ************************************************************************/ 13845dfecf96Smrgstatic void 13855dfecf96Smrgsqrt_real(n_real *real) 13865dfecf96Smrg{ 13875dfecf96Smrg switch (RTYPE(real)) { 13885dfecf96Smrg case N_FIXNUM: 13895dfecf96Smrg case N_BIGNUM: 13905dfecf96Smrg rsqrt_xi(real); 13915dfecf96Smrg break; 13925dfecf96Smrg case N_FLONUM: 13935dfecf96Smrg rsqrt_ff(real); 13945dfecf96Smrg break; 13955dfecf96Smrg case N_FIXRATIO: 13965dfecf96Smrg case N_BIGRATIO: 13975dfecf96Smrg rsqrt_xr(real); 13985dfecf96Smrg break; 13995dfecf96Smrg } 14005dfecf96Smrg} 14015dfecf96Smrg 14025dfecf96Smrgstatic void 14035dfecf96Smrgsqrt_number(n_number *num) 14045dfecf96Smrg{ 14055dfecf96Smrg if (num->complex) 14065dfecf96Smrg nsqrt_cx(num); 14075dfecf96Smrg else { 14085dfecf96Smrg switch (NRTYPE(num)) { 14095dfecf96Smrg case N_FIXNUM: 14105dfecf96Smrg case N_BIGNUM: 14115dfecf96Smrg nsqrt_xi(num); 14125dfecf96Smrg break; 14135dfecf96Smrg case N_FLONUM: 14145dfecf96Smrg nsqrt_ff(num); 14155dfecf96Smrg break; 14165dfecf96Smrg case N_FIXRATIO: 14175dfecf96Smrg case N_BIGRATIO: 14185dfecf96Smrg nsqrt_xr(num); 14195dfecf96Smrg break; 14205dfecf96Smrg } 14215dfecf96Smrg } 14225dfecf96Smrg} 14235dfecf96Smrg 14245dfecf96Smrgstatic void 14255dfecf96Smrgrsqrt_xi(n_real *real) 14265dfecf96Smrg{ 14275dfecf96Smrg int exact; 14285dfecf96Smrg mpi bignum; 14295dfecf96Smrg 14305dfecf96Smrg if (cmp_real_real(real, &zero) < 0) 14315dfecf96Smrg fatal_error(FLOATING_POINT_EXCEPTION); 14325dfecf96Smrg 14335dfecf96Smrg mpi_init(&bignum); 14345dfecf96Smrg if (RTYPE(real) == N_BIGNUM) 14355dfecf96Smrg exact = mpi_sqrt(&bignum, RBI(real)); 14365dfecf96Smrg else { 14375dfecf96Smrg mpi tmp; 14385dfecf96Smrg 14395dfecf96Smrg mpi_init(&tmp); 14405dfecf96Smrg mpi_seti(&tmp, RFI(real)); 14415dfecf96Smrg exact = mpi_sqrt(&bignum, &tmp); 14425dfecf96Smrg mpi_clear(&tmp); 14435dfecf96Smrg } 14445dfecf96Smrg if (exact) { 14455dfecf96Smrg if (RTYPE(real) == N_BIGNUM) { 14465dfecf96Smrg mpi_set(RBI(real), &bignum); 14475dfecf96Smrg rbi_canonicalize(real); 14485dfecf96Smrg } 14495dfecf96Smrg else 14505dfecf96Smrg RFI(real) = mpi_geti(&bignum); 14515dfecf96Smrg } 14525dfecf96Smrg else { 14535dfecf96Smrg double value; 14545dfecf96Smrg 14555dfecf96Smrg if (RTYPE(real) == N_BIGNUM) { 14565dfecf96Smrg value = bi_getd(RBI(real)); 14575dfecf96Smrg RCLEAR_BI(real); 14585dfecf96Smrg } 14595dfecf96Smrg else 14605dfecf96Smrg value = (double)RFI(real); 14615dfecf96Smrg 14625dfecf96Smrg value = sqrt(value); 14635dfecf96Smrg RTYPE(real) = N_FLONUM; 14645dfecf96Smrg RFF(real) = value; 14655dfecf96Smrg } 14665dfecf96Smrg mpi_clear(&bignum); 14675dfecf96Smrg} 14685dfecf96Smrg 14695dfecf96Smrgstatic void 14705dfecf96Smrgrsqrt_xr(n_real *real) 14715dfecf96Smrg{ 14725dfecf96Smrg n_real num, den; 14735dfecf96Smrg 14745dfecf96Smrg if (cmp_real_real(real, &zero) < 0) 14755dfecf96Smrg fatal_error(FLOATING_POINT_EXCEPTION); 14765dfecf96Smrg 14775dfecf96Smrg if (RTYPE(real) == N_FIXRATIO) { 14785dfecf96Smrg num.type = den.type = N_FIXNUM; 14795dfecf96Smrg num.data.fixnum = RFRN(real); 14805dfecf96Smrg den.data.fixnum = RFRD(real); 14815dfecf96Smrg } 14825dfecf96Smrg else { 14835dfecf96Smrg mpi *bignum; 14845dfecf96Smrg 14855dfecf96Smrg if (mpi_fiti(RBRN(real))) { 14865dfecf96Smrg num.type = N_FIXNUM; 14875dfecf96Smrg num.data.fixnum = mpi_geti(RBRN(real)); 14885dfecf96Smrg } 14895dfecf96Smrg else { 14905dfecf96Smrg bignum = XALLOC(mpi); 14915dfecf96Smrg mpi_init(bignum); 14925dfecf96Smrg mpi_set(bignum, RBRN(real)); 14935dfecf96Smrg num.type = N_BIGNUM; 14945dfecf96Smrg num.data.bignum = bignum; 14955dfecf96Smrg } 14965dfecf96Smrg 14975dfecf96Smrg if (mpi_fiti(RBRD(real))) { 14985dfecf96Smrg den.type = N_FIXNUM; 14995dfecf96Smrg den.data.fixnum = mpi_geti(RBRD(real)); 15005dfecf96Smrg } 15015dfecf96Smrg else { 15025dfecf96Smrg bignum = XALLOC(mpi); 15035dfecf96Smrg mpi_init(bignum); 15045dfecf96Smrg mpi_set(bignum, RBRD(real)); 15055dfecf96Smrg den.type = N_BIGNUM; 15065dfecf96Smrg den.data.bignum = bignum; 15075dfecf96Smrg } 15085dfecf96Smrg } 15095dfecf96Smrg 15105dfecf96Smrg rsqrt_xi(&num); 15115dfecf96Smrg rsqrt_xi(&den); 15125dfecf96Smrg 15135dfecf96Smrg clear_real(real); 15145dfecf96Smrg memcpy(real, &num, sizeof(n_real)); 15155dfecf96Smrg div_real_real(real, &den); 15165dfecf96Smrg clear_real(&den); 15175dfecf96Smrg} 15185dfecf96Smrg 15195dfecf96Smrgstatic void 15205dfecf96Smrgrsqrt_ff(n_real *real) 15215dfecf96Smrg{ 15225dfecf96Smrg if (RFF(real) < 0.0) 15235dfecf96Smrg fatal_error(FLOATING_POINT_EXCEPTION); 15245dfecf96Smrg RFF(real) = sqrt(RFF(real)); 15255dfecf96Smrg} 15265dfecf96Smrg 15275dfecf96Smrg 15285dfecf96Smrgstatic void 15295dfecf96Smrgnsqrt_cx(n_number *num) 15305dfecf96Smrg{ 15315dfecf96Smrg n_number mag; 15325dfecf96Smrg n_real *real, *imag; 15335dfecf96Smrg 15345dfecf96Smrg real = &(mag.real); 15355dfecf96Smrg imag = &(mag.imag); 15365dfecf96Smrg set_real_real(real, NREAL(num)); 15375dfecf96Smrg set_real_real(imag, NIMAG(num)); 15385dfecf96Smrg mag.complex = 1; 15395dfecf96Smrg 15405dfecf96Smrg nabs_cx(&mag); /* this will free the imag part data */ 15415dfecf96Smrg if (cmp_real_real(real, &zero) == 0) { 15425dfecf96Smrg clear_number(num); 15435dfecf96Smrg memcpy(NREAL(num), real, sizeof(n_real)); 15445dfecf96Smrg clear_real(real); 15455dfecf96Smrg num->complex = 0; 15465dfecf96Smrg return; 15475dfecf96Smrg } 15485dfecf96Smrg else if (cmp_real_real(NREAL(num), &zero) > 0) { 15495dfecf96Smrg /* R = sqrt((mag + Ra) / 2) */ 15505dfecf96Smrg add_real_real(NREAL(num), real); 15515dfecf96Smrg clear_real(real); 15525dfecf96Smrg div_real_real(NREAL(num), &two); 15535dfecf96Smrg sqrt_real(NREAL(num)); 15545dfecf96Smrg 15555dfecf96Smrg /* I = Ia / R / 2 */ 15565dfecf96Smrg div_real_real(NIMAG(num), NREAL(num)); 15575dfecf96Smrg div_real_real(NIMAG(num), &two); 15585dfecf96Smrg } 15595dfecf96Smrg else { 15605dfecf96Smrg /* remember old imag part */ 15615dfecf96Smrg memcpy(imag, NIMAG(num), sizeof(n_real)); 15625dfecf96Smrg 15635dfecf96Smrg /* I = sqrt((mag - Ra) / 2) */ 15645dfecf96Smrg memcpy(NIMAG(num), real, sizeof(n_real)); 15655dfecf96Smrg sub_real_real(NIMAG(num), NREAL(num)); 15665dfecf96Smrg div_real_real(NIMAG(num), &two); 15675dfecf96Smrg sqrt_real(NIMAG(num)); 15685dfecf96Smrg if (cmp_real_real(imag, &zero) < 0) 15695dfecf96Smrg neg_real(NIMAG(num)); 15705dfecf96Smrg 15715dfecf96Smrg /* R = Ia / I / 2 */ 15725dfecf96Smrg clear_real(NREAL(num)); 15735dfecf96Smrg /* start with old imag part */ 15745dfecf96Smrg memcpy(NREAL(num), imag, sizeof(n_real)); 15755dfecf96Smrg div_real_real(NREAL(num), NIMAG(num)); 15765dfecf96Smrg div_real_real(NREAL(num), &two); 15775dfecf96Smrg } 15785dfecf96Smrg 15795dfecf96Smrg ncx_canonicalize(num); 15805dfecf96Smrg} 15815dfecf96Smrg 15825dfecf96Smrgstatic void 15835dfecf96Smrgnsqrt_xi(n_number *num) 15845dfecf96Smrg{ 15855dfecf96Smrg if (cmp_real_real(NREAL(num), &zero) < 0) { 15865dfecf96Smrg memcpy(NIMAG(num), NREAL(num), sizeof(n_real)); 15875dfecf96Smrg neg_real(NIMAG(num)); 15885dfecf96Smrg rsqrt_xi(NIMAG(num)); 15895dfecf96Smrg NRTYPE(num) = N_FIXNUM; 15905dfecf96Smrg NRFI(num) = 0; 15915dfecf96Smrg num->complex = 1; 15925dfecf96Smrg } 15935dfecf96Smrg else 15945dfecf96Smrg rsqrt_xi(NREAL(num)); 15955dfecf96Smrg} 15965dfecf96Smrg 15975dfecf96Smrgstatic void 15985dfecf96Smrgnsqrt_ff(n_number *num) 15995dfecf96Smrg{ 16005dfecf96Smrg double value; 16015dfecf96Smrg 16025dfecf96Smrg if (NRFF(num) < 0.0) { 16035dfecf96Smrg value = sqrt(-NRFF(num)); 16045dfecf96Smrg 16055dfecf96Smrg NITYPE(num) = N_FLONUM; 16065dfecf96Smrg NIFF(num) = value; 16075dfecf96Smrg NRTYPE(num) = N_FIXNUM; 16085dfecf96Smrg NRFI(num) = 0; 16095dfecf96Smrg num->complex = 1; 16105dfecf96Smrg } 16115dfecf96Smrg else { 16125dfecf96Smrg value = sqrt(NRFF(num)); 16135dfecf96Smrg NRFF(num) = value; 16145dfecf96Smrg } 16155dfecf96Smrg} 16165dfecf96Smrg 16175dfecf96Smrgstatic void 16185dfecf96Smrgnsqrt_xr(n_number *num) 16195dfecf96Smrg{ 16205dfecf96Smrg if (cmp_real_real(NREAL(num), &zero) < 0) { 16215dfecf96Smrg memcpy(NIMAG(num), NREAL(num), sizeof(n_real)); 16225dfecf96Smrg neg_real(NIMAG(num)); 16235dfecf96Smrg rsqrt_xr(NIMAG(num)); 16245dfecf96Smrg NRTYPE(num) = N_FIXNUM; 16255dfecf96Smrg NRFI(num) = 0; 16265dfecf96Smrg num->complex = 1; 16275dfecf96Smrg } 16285dfecf96Smrg else 16295dfecf96Smrg rsqrt_xr(NREAL(num)); 16305dfecf96Smrg} 16315dfecf96Smrg 16325dfecf96Smrg 16335dfecf96Smrg/************************************************************************ 16345dfecf96Smrg * MOD 16355dfecf96Smrg ************************************************************************/ 16365dfecf96Smrgstatic void 16375dfecf96Smrgmod_real_real(n_real *real, n_real *val) 16385dfecf96Smrg{ 16395dfecf96Smrg /* Assume both operands are integers */ 16405dfecf96Smrg switch (RTYPE(real)) { 16415dfecf96Smrg case N_FIXNUM: 16425dfecf96Smrg switch (RTYPE(val)) { 16435dfecf96Smrg case N_FIXNUM: 16445dfecf96Smrg rmod_fi_fi(real, RFI(val)); 16455dfecf96Smrg break; 16465dfecf96Smrg case N_BIGNUM: 16475dfecf96Smrg rmod_fi_bi(real, RBI(val)); 16485dfecf96Smrg break; 16495dfecf96Smrg } 16505dfecf96Smrg break; 16515dfecf96Smrg case N_BIGNUM: 16525dfecf96Smrg switch (RTYPE(val)) { 16535dfecf96Smrg case N_FIXNUM: 16545dfecf96Smrg rmod_bi_fi(real, RFI(val)); 16555dfecf96Smrg break; 16565dfecf96Smrg case N_BIGNUM: 16575dfecf96Smrg rmod_bi_bi(real, RBI(val)); 16585dfecf96Smrg break; 16595dfecf96Smrg } 16605dfecf96Smrg break; 16615dfecf96Smrg } 16625dfecf96Smrg} 16635dfecf96Smrg 16645dfecf96Smrgstatic void 16655dfecf96Smrgmod_real_object(n_real *real, LispObj *obj) 16665dfecf96Smrg{ 16675dfecf96Smrg switch (RTYPE(real)) { 16685dfecf96Smrg case N_FIXNUM: 16695dfecf96Smrg switch (OBJECT_TYPE(obj)) { 16705dfecf96Smrg case LispFixnum_t: 16715dfecf96Smrg rmod_fi_fi(real, OFI(obj)); 16725dfecf96Smrg return; 16735dfecf96Smrg case LispInteger_t: 16745dfecf96Smrg rmod_fi_fi(real, OII(obj)); 16755dfecf96Smrg return; 16765dfecf96Smrg case LispBignum_t: 16775dfecf96Smrg rmod_fi_bi(real, OBI(obj)); 16785dfecf96Smrg return; 16795dfecf96Smrg default: 16805dfecf96Smrg break; 16815dfecf96Smrg } 16825dfecf96Smrg break; 16835dfecf96Smrg case N_BIGNUM: 16845dfecf96Smrg switch (OBJECT_TYPE(obj)) { 16855dfecf96Smrg case LispFixnum_t: 16865dfecf96Smrg rmod_bi_fi(real, OFI(obj)); 16875dfecf96Smrg return; 16885dfecf96Smrg case LispInteger_t: 16895dfecf96Smrg rmod_bi_fi(real, OII(obj)); 16905dfecf96Smrg return; 16915dfecf96Smrg case LispBignum_t: 16925dfecf96Smrg rmod_bi_bi(real, OBI(obj)); 16935dfecf96Smrg return; 16945dfecf96Smrg default: 16955dfecf96Smrg break; 16965dfecf96Smrg } 16975dfecf96Smrg break; 16985dfecf96Smrg /* Assume the n_real object is an integer */ 16995dfecf96Smrg } 17005dfecf96Smrg fatal_object_error(obj, NOT_AN_INTEGER); 17015dfecf96Smrg} 17025dfecf96Smrg 17035dfecf96Smrgstatic void 17045dfecf96Smrgrmod_fi_fi(n_real *real, long fi) 17055dfecf96Smrg{ 17065dfecf96Smrg if (fi == 0) 17075dfecf96Smrg fatal_error(DIVIDE_BY_ZERO); 17085dfecf96Smrg 17095dfecf96Smrg if ((RFI(real) < 0) ^ (fi < 0)) 17105dfecf96Smrg RFI(real) = (RFI(real) % fi) + fi; 17115dfecf96Smrg else if (RFI(real) == MINSLONG || fi == MINSLONG) { 17125dfecf96Smrg mpi bignum; 17135dfecf96Smrg 17145dfecf96Smrg mpi_init(&bignum); 17155dfecf96Smrg mpi_seti(&bignum, RFI(real)); 17165dfecf96Smrg RFI(real) = mpi_modi(&bignum, fi); 17175dfecf96Smrg mpi_clear(&bignum); 17185dfecf96Smrg } 17195dfecf96Smrg else 17205dfecf96Smrg RFI(real) = RFI(real) % fi; 17215dfecf96Smrg} 17225dfecf96Smrg 17235dfecf96Smrgstatic void 17245dfecf96Smrgrmod_fi_bi(n_real *real, mpi *bignum) 17255dfecf96Smrg{ 17265dfecf96Smrg mpi *bigi; 17275dfecf96Smrg 17285dfecf96Smrg if (mpi_cmpi(bignum, 0) == 0) 17295dfecf96Smrg fatal_error(DIVIDE_BY_ZERO); 17305dfecf96Smrg 17315dfecf96Smrg bigi = XALLOC(mpi); 17325dfecf96Smrg mpi_init(bigi); 17335dfecf96Smrg mpi_seti(bigi, RFI(real)); 17345dfecf96Smrg mpi_mod(bigi, bigi, bignum); 17355dfecf96Smrg RTYPE(real) = N_BIGNUM; 17365dfecf96Smrg RBI(real) = bigi; 17375dfecf96Smrg rbi_canonicalize(real); 17385dfecf96Smrg} 17395dfecf96Smrg 17405dfecf96Smrgstatic void 17415dfecf96Smrgrmod_bi_fi(n_real *real, long fi) 17425dfecf96Smrg{ 17435dfecf96Smrg mpi iop; 17445dfecf96Smrg 17455dfecf96Smrg if (fi == 0) 17465dfecf96Smrg fatal_error(DIVIDE_BY_ZERO); 17475dfecf96Smrg 17485dfecf96Smrg mpi_init(&iop); 17495dfecf96Smrg mpi_seti(&iop, fi); 17505dfecf96Smrg mpi_mod(RBI(real), RBI(real), &iop); 17515dfecf96Smrg mpi_clear(&iop); 17525dfecf96Smrg rbi_canonicalize(real); 17535dfecf96Smrg} 17545dfecf96Smrg 17555dfecf96Smrgstatic void 17565dfecf96Smrgrmod_bi_bi(n_real *real, mpi *bignum) 17575dfecf96Smrg{ 17585dfecf96Smrg if (mpi_cmpi(bignum, 0) == 0) 17595dfecf96Smrg fatal_error(DIVIDE_BY_ZERO); 17605dfecf96Smrg 17615dfecf96Smrg mpi_mod(RBI(real), RBI(real), bignum); 17625dfecf96Smrg rbi_canonicalize(real); 17635dfecf96Smrg} 17645dfecf96Smrg 17655dfecf96Smrg/************************************************************************ 17665dfecf96Smrg * REM 17675dfecf96Smrg ************************************************************************/ 17685dfecf96Smrgstatic void 17695dfecf96Smrgrem_real_object(n_real *real, LispObj *obj) 17705dfecf96Smrg{ 17715dfecf96Smrg switch (RTYPE(real)) { 17725dfecf96Smrg case N_FIXNUM: 17735dfecf96Smrg switch (OBJECT_TYPE(obj)) { 17745dfecf96Smrg case LispFixnum_t: 17755dfecf96Smrg rrem_fi_fi(real, OFI(obj)); 17765dfecf96Smrg return; 17775dfecf96Smrg case LispInteger_t: 17785dfecf96Smrg rrem_fi_fi(real, OII(obj)); 17795dfecf96Smrg return; 17805dfecf96Smrg case LispBignum_t: 17815dfecf96Smrg rrem_fi_bi(real, OBI(obj)); 17825dfecf96Smrg return; 17835dfecf96Smrg default: 17845dfecf96Smrg break; 17855dfecf96Smrg } 17865dfecf96Smrg break; 17875dfecf96Smrg case N_BIGNUM: 17885dfecf96Smrg switch (OBJECT_TYPE(obj)) { 17895dfecf96Smrg case LispFixnum_t: 17905dfecf96Smrg rrem_bi_fi(real, OFI(obj)); 17915dfecf96Smrg return; 17925dfecf96Smrg case LispInteger_t: 17935dfecf96Smrg rrem_bi_fi(real, OII(obj)); 17945dfecf96Smrg return; 17955dfecf96Smrg case LispBignum_t: 17965dfecf96Smrg rrem_bi_bi(real, OBI(obj)); 17975dfecf96Smrg return; 17985dfecf96Smrg default: 17995dfecf96Smrg break; 18005dfecf96Smrg } 18015dfecf96Smrg break; 18025dfecf96Smrg /* Assume the n_real object is an integer */ 18035dfecf96Smrg } 18045dfecf96Smrg fatal_object_error(obj, NOT_AN_INTEGER); 18055dfecf96Smrg} 18065dfecf96Smrg 18075dfecf96Smrgstatic void 18085dfecf96Smrgrrem_fi_fi(n_real *real, long fi) 18095dfecf96Smrg{ 18105dfecf96Smrg if (fi == 0) 18115dfecf96Smrg fatal_error(DIVIDE_BY_ZERO); 18125dfecf96Smrg 18135dfecf96Smrg if (RFI(real) == MINSLONG || fi == MINSLONG) { 18145dfecf96Smrg mpi bignum; 18155dfecf96Smrg 18165dfecf96Smrg mpi_init(&bignum); 18175dfecf96Smrg mpi_seti(&bignum, RFI(real)); 18185dfecf96Smrg RFI(real) = mpi_remi(&bignum, fi); 18195dfecf96Smrg mpi_clear(&bignum); 18205dfecf96Smrg } 18215dfecf96Smrg else 18225dfecf96Smrg RFI(real) = RFI(real) % fi; 18235dfecf96Smrg} 18245dfecf96Smrg 18255dfecf96Smrgstatic void 18265dfecf96Smrgrrem_fi_bi(n_real *real, mpi *bignum) 18275dfecf96Smrg{ 18285dfecf96Smrg mpi *bigi; 18295dfecf96Smrg 18305dfecf96Smrg if (mpi_cmpi(bignum, 0) == 0) 18315dfecf96Smrg fatal_error(DIVIDE_BY_ZERO); 18325dfecf96Smrg 18335dfecf96Smrg bigi = XALLOC(mpi); 18345dfecf96Smrg mpi_init(bigi); 18355dfecf96Smrg mpi_seti(bigi, RFI(real)); 18365dfecf96Smrg mpi_rem(bigi, bigi, bignum); 18375dfecf96Smrg RTYPE(real) = N_BIGNUM; 18385dfecf96Smrg RBI(real) = bigi; 18395dfecf96Smrg rbi_canonicalize(real); 18405dfecf96Smrg} 18415dfecf96Smrg 18425dfecf96Smrgstatic void 18435dfecf96Smrgrrem_bi_fi(n_real *real, long fi) 18445dfecf96Smrg{ 18455dfecf96Smrg mpi iop; 18465dfecf96Smrg 18475dfecf96Smrg if (fi == 0) 18485dfecf96Smrg fatal_error(DIVIDE_BY_ZERO); 18495dfecf96Smrg 18505dfecf96Smrg mpi_init(&iop); 18515dfecf96Smrg mpi_seti(&iop, fi); 18525dfecf96Smrg mpi_rem(RBI(real), RBI(real), &iop); 18535dfecf96Smrg mpi_clear(&iop); 18545dfecf96Smrg rbi_canonicalize(real); 18555dfecf96Smrg} 18565dfecf96Smrg 18575dfecf96Smrgstatic void 18585dfecf96Smrgrrem_bi_bi(n_real *real, mpi *bignum) 18595dfecf96Smrg{ 18605dfecf96Smrg if (mpi_cmpi(bignum, 0) == 0) 18615dfecf96Smrg fatal_error(DIVIDE_BY_ZERO); 18625dfecf96Smrg 18635dfecf96Smrg mpi_rem(RBI(real), RBI(real), bignum); 18645dfecf96Smrg rbi_canonicalize(real); 18655dfecf96Smrg} 18665dfecf96Smrg 18675dfecf96Smrg 18685dfecf96Smrg/************************************************************************ 18695dfecf96Smrg * GCD 18705dfecf96Smrg ************************************************************************/ 18715dfecf96Smrgstatic void 18725dfecf96Smrggcd_real_object(n_real *real, LispObj *obj) 18735dfecf96Smrg{ 18745dfecf96Smrg if (!INTEGERP(obj)) 18755dfecf96Smrg fatal_object_error(obj, NOT_AN_INTEGER); 18765dfecf96Smrg 18775dfecf96Smrg /* check for zero operand */ 18785dfecf96Smrg if (cmp_real_real(real, &zero) == 0) 18795dfecf96Smrg set_real_object(real, obj); 18805dfecf96Smrg else if (cmp_real_object(&zero, obj) != 0) { 18815dfecf96Smrg n_real rest, temp; 18825dfecf96Smrg 18835dfecf96Smrg set_real_object(&rest, obj); 18845dfecf96Smrg for (;;) { 18855dfecf96Smrg mod_real_real(&rest, real); 18865dfecf96Smrg if (cmp_real_real(&rest, &zero) == 0) 18875dfecf96Smrg break; 18885dfecf96Smrg memcpy(&temp, real, sizeof(n_real)); 18895dfecf96Smrg memcpy(real, &rest, sizeof(n_real)); 18905dfecf96Smrg memcpy(&rest, &temp, sizeof(n_real)); 18915dfecf96Smrg } 18925dfecf96Smrg clear_real(&rest); 18935dfecf96Smrg } 18945dfecf96Smrg} 18955dfecf96Smrg 18965dfecf96Smrg/************************************************************************ 18975dfecf96Smrg * AND 18985dfecf96Smrg ************************************************************************/ 18995dfecf96Smrgstatic void 19005dfecf96Smrgand_real_object(n_real *real, LispObj *obj) 19015dfecf96Smrg{ 19025dfecf96Smrg mpi *bigi, iop; 19035dfecf96Smrg 19045dfecf96Smrg switch (OBJECT_TYPE(obj)) { 19055dfecf96Smrg case LispFixnum_t: 19065dfecf96Smrg switch (RTYPE(real)) { 19075dfecf96Smrg case N_FIXNUM: 19085dfecf96Smrg RFI(real) &= OFI(obj); 19095dfecf96Smrg break; 19105dfecf96Smrg case N_BIGNUM: 19115dfecf96Smrg mpi_init(&iop); 19125dfecf96Smrg mpi_seti(&iop, OFI(obj)); 19135dfecf96Smrg mpi_and(RBI(real), RBI(real), &iop); 19145dfecf96Smrg mpi_clear(&iop); 19155dfecf96Smrg rbi_canonicalize(real); 19165dfecf96Smrg break; 19175dfecf96Smrg } 19185dfecf96Smrg break; 19195dfecf96Smrg case LispInteger_t: 19205dfecf96Smrg switch (RTYPE(real)) { 19215dfecf96Smrg case N_FIXNUM: 19225dfecf96Smrg RFI(real) &= OII(obj); 19235dfecf96Smrg break; 19245dfecf96Smrg case N_BIGNUM: 19255dfecf96Smrg mpi_init(&iop); 19265dfecf96Smrg mpi_seti(&iop, OII(obj)); 19275dfecf96Smrg mpi_and(RBI(real), RBI(real), &iop); 19285dfecf96Smrg mpi_clear(&iop); 19295dfecf96Smrg rbi_canonicalize(real); 19305dfecf96Smrg break; 19315dfecf96Smrg } 19325dfecf96Smrg break; 19335dfecf96Smrg case LispBignum_t: 19345dfecf96Smrg switch (RTYPE(real)) { 19355dfecf96Smrg case N_FIXNUM: 19365dfecf96Smrg bigi = XALLOC(mpi); 19375dfecf96Smrg mpi_init(bigi); 19385dfecf96Smrg mpi_seti(bigi, RFI(real)); 19395dfecf96Smrg mpi_and(bigi, bigi, OBI(obj)); 19405dfecf96Smrg RTYPE(real) = N_BIGNUM; 19415dfecf96Smrg RBI(real) = bigi; 19425dfecf96Smrg rbi_canonicalize(real); 19435dfecf96Smrg break; 19445dfecf96Smrg case N_BIGNUM: 19455dfecf96Smrg mpi_and(RBI(real), RBI(real), OBI(obj)); 19465dfecf96Smrg rbi_canonicalize(real); 19475dfecf96Smrg break; 19485dfecf96Smrg } 19495dfecf96Smrg break; 19505dfecf96Smrg default: 19515dfecf96Smrg fatal_object_error(obj, NOT_AN_INTEGER); 19525dfecf96Smrg break; 19535dfecf96Smrg } 19545dfecf96Smrg} 19555dfecf96Smrg 19565dfecf96Smrg 19575dfecf96Smrg/************************************************************************ 19585dfecf96Smrg * EQV 19595dfecf96Smrg ************************************************************************/ 19605dfecf96Smrgstatic void 19615dfecf96Smrgeqv_real_object(n_real *real, LispObj *obj) 19625dfecf96Smrg{ 19635dfecf96Smrg mpi *bigi, iop; 19645dfecf96Smrg 19655dfecf96Smrg switch (OBJECT_TYPE(obj)) { 19665dfecf96Smrg case LispFixnum_t: 19675dfecf96Smrg switch (RTYPE(real)) { 19685dfecf96Smrg case N_FIXNUM: 19695dfecf96Smrg RFI(real) ^= ~OFI(obj); 19705dfecf96Smrg break; 19715dfecf96Smrg case N_BIGNUM: 19725dfecf96Smrg mpi_init(&iop); 19735dfecf96Smrg mpi_seti(&iop, OFI(obj)); 19745dfecf96Smrg mpi_com(&iop, &iop); 19755dfecf96Smrg mpi_xor(RBI(real), RBI(real), &iop); 19765dfecf96Smrg mpi_clear(&iop); 19775dfecf96Smrg rbi_canonicalize(real); 19785dfecf96Smrg break; 19795dfecf96Smrg } 19805dfecf96Smrg break; 19815dfecf96Smrg case LispInteger_t: 19825dfecf96Smrg switch (RTYPE(real)) { 19835dfecf96Smrg case N_FIXNUM: 19845dfecf96Smrg RFI(real) ^= ~OII(obj); 19855dfecf96Smrg break; 19865dfecf96Smrg case N_BIGNUM: 19875dfecf96Smrg mpi_init(&iop); 19885dfecf96Smrg mpi_seti(&iop, OII(obj)); 19895dfecf96Smrg mpi_com(&iop, &iop); 19905dfecf96Smrg mpi_xor(RBI(real), RBI(real), &iop); 19915dfecf96Smrg mpi_clear(&iop); 19925dfecf96Smrg rbi_canonicalize(real); 19935dfecf96Smrg break; 19945dfecf96Smrg } 19955dfecf96Smrg break; 19965dfecf96Smrg case LispBignum_t: 19975dfecf96Smrg switch (RTYPE(real)) { 19985dfecf96Smrg case N_FIXNUM: 19995dfecf96Smrg bigi = XALLOC(mpi); 20005dfecf96Smrg mpi_init(bigi); 20015dfecf96Smrg mpi_seti(bigi, RFI(real)); 20025dfecf96Smrg mpi_com(bigi, bigi); 20035dfecf96Smrg mpi_xor(bigi, bigi, OBI(obj)); 20045dfecf96Smrg RTYPE(real) = N_BIGNUM; 20055dfecf96Smrg RBI(real) = bigi; 20065dfecf96Smrg rbi_canonicalize(real); 20075dfecf96Smrg break; 20085dfecf96Smrg case N_BIGNUM: 20095dfecf96Smrg mpi_com(RBI(real), RBI(real)); 20105dfecf96Smrg mpi_xor(RBI(real), RBI(real), OBI(obj)); 20115dfecf96Smrg rbi_canonicalize(real); 20125dfecf96Smrg break; 20135dfecf96Smrg } 20145dfecf96Smrg break; 20155dfecf96Smrg default: 20165dfecf96Smrg fatal_object_error(obj, NOT_AN_INTEGER); 20175dfecf96Smrg break; 20185dfecf96Smrg } 20195dfecf96Smrg} 20205dfecf96Smrg 20215dfecf96Smrg 20225dfecf96Smrg/************************************************************************ 20235dfecf96Smrg * IOR 20245dfecf96Smrg ************************************************************************/ 20255dfecf96Smrgstatic void 20265dfecf96Smrgior_real_object(n_real *real, LispObj *obj) 20275dfecf96Smrg{ 20285dfecf96Smrg mpi *bigi, iop; 20295dfecf96Smrg 20305dfecf96Smrg switch (OBJECT_TYPE(obj)) { 20315dfecf96Smrg case LispFixnum_t: 20325dfecf96Smrg switch (RTYPE(real)) { 20335dfecf96Smrg case N_FIXNUM: 20345dfecf96Smrg RFI(real) |= OFI(obj); 20355dfecf96Smrg break; 20365dfecf96Smrg case N_BIGNUM: 20375dfecf96Smrg mpi_init(&iop); 20385dfecf96Smrg mpi_seti(&iop, OFI(obj)); 20395dfecf96Smrg mpi_ior(RBI(real), RBI(real), &iop); 20405dfecf96Smrg mpi_clear(&iop); 20415dfecf96Smrg rbi_canonicalize(real); 20425dfecf96Smrg break; 20435dfecf96Smrg } 20445dfecf96Smrg break; 20455dfecf96Smrg case LispInteger_t: 20465dfecf96Smrg switch (RTYPE(real)) { 20475dfecf96Smrg case N_FIXNUM: 20485dfecf96Smrg RFI(real) |= OII(obj); 20495dfecf96Smrg break; 20505dfecf96Smrg case N_BIGNUM: 20515dfecf96Smrg mpi_init(&iop); 20525dfecf96Smrg mpi_seti(&iop, OII(obj)); 20535dfecf96Smrg mpi_ior(RBI(real), RBI(real), &iop); 20545dfecf96Smrg mpi_clear(&iop); 20555dfecf96Smrg rbi_canonicalize(real); 20565dfecf96Smrg break; 20575dfecf96Smrg } 20585dfecf96Smrg break; 20595dfecf96Smrg case LispBignum_t: 20605dfecf96Smrg switch (RTYPE(real)) { 20615dfecf96Smrg case N_FIXNUM: 20625dfecf96Smrg bigi = XALLOC(mpi); 20635dfecf96Smrg mpi_init(bigi); 20645dfecf96Smrg mpi_seti(bigi, RFI(real)); 20655dfecf96Smrg mpi_ior(bigi, bigi, OBI(obj)); 20665dfecf96Smrg RTYPE(real) = N_BIGNUM; 20675dfecf96Smrg RBI(real) = bigi; 20685dfecf96Smrg rbi_canonicalize(real); 20695dfecf96Smrg break; 20705dfecf96Smrg case N_BIGNUM: 20715dfecf96Smrg mpi_ior(RBI(real), RBI(real), OBI(obj)); 20725dfecf96Smrg rbi_canonicalize(real); 20735dfecf96Smrg break; 20745dfecf96Smrg } 20755dfecf96Smrg break; 20765dfecf96Smrg default: 20775dfecf96Smrg fatal_object_error(obj, NOT_AN_INTEGER); 20785dfecf96Smrg break; 20795dfecf96Smrg } 20805dfecf96Smrg} 20815dfecf96Smrg 20825dfecf96Smrg 20835dfecf96Smrg/************************************************************************ 20845dfecf96Smrg * NOT 20855dfecf96Smrg ************************************************************************/ 20865dfecf96Smrgstatic void 20875dfecf96Smrgnot_real(n_real *real) 20885dfecf96Smrg{ 20895dfecf96Smrg if (RTYPE(real) == N_FIXNUM) 20905dfecf96Smrg RFI(real) = ~RFI(real); 20915dfecf96Smrg else { 20925dfecf96Smrg mpi_com(RBI(real), RBI(real)); 20935dfecf96Smrg rbi_canonicalize(real); 20945dfecf96Smrg } 20955dfecf96Smrg} 20965dfecf96Smrg 20975dfecf96Smrg/************************************************************************ 20985dfecf96Smrg * XOR 20995dfecf96Smrg ************************************************************************/ 21005dfecf96Smrgstatic void 21015dfecf96Smrgxor_real_object(n_real *real, LispObj *obj) 21025dfecf96Smrg{ 21035dfecf96Smrg mpi *bigi, iop; 21045dfecf96Smrg 21055dfecf96Smrg switch (OBJECT_TYPE(obj)) { 21065dfecf96Smrg case LispFixnum_t: 21075dfecf96Smrg switch (RTYPE(real)) { 21085dfecf96Smrg case N_FIXNUM: 21095dfecf96Smrg RFI(real) ^= OFI(obj); 21105dfecf96Smrg break; 21115dfecf96Smrg case N_BIGNUM: 21125dfecf96Smrg mpi_init(&iop); 21135dfecf96Smrg mpi_seti(&iop, OFI(obj)); 21145dfecf96Smrg mpi_xor(RBI(real), RBI(real), &iop); 21155dfecf96Smrg mpi_clear(&iop); 21165dfecf96Smrg rbi_canonicalize(real); 21175dfecf96Smrg break; 21185dfecf96Smrg } 21195dfecf96Smrg break; 21205dfecf96Smrg case LispInteger_t: 21215dfecf96Smrg switch (RTYPE(real)) { 21225dfecf96Smrg case N_FIXNUM: 21235dfecf96Smrg RFI(real) ^= OII(obj); 21245dfecf96Smrg break; 21255dfecf96Smrg case N_BIGNUM: 21265dfecf96Smrg mpi_init(&iop); 21275dfecf96Smrg mpi_seti(&iop, OII(obj)); 21285dfecf96Smrg mpi_xor(RBI(real), RBI(real), &iop); 21295dfecf96Smrg mpi_clear(&iop); 21305dfecf96Smrg rbi_canonicalize(real); 21315dfecf96Smrg break; 21325dfecf96Smrg } 21335dfecf96Smrg break; 21345dfecf96Smrg case LispBignum_t: 21355dfecf96Smrg switch (RTYPE(real)) { 21365dfecf96Smrg case N_FIXNUM: 21375dfecf96Smrg bigi = XALLOC(mpi); 21385dfecf96Smrg mpi_init(bigi); 21395dfecf96Smrg mpi_seti(bigi, RFI(real)); 21405dfecf96Smrg mpi_xor(bigi, bigi, OBI(obj)); 21415dfecf96Smrg RTYPE(real) = N_BIGNUM; 21425dfecf96Smrg RBI(real) = bigi; 21435dfecf96Smrg rbi_canonicalize(real); 21445dfecf96Smrg break; 21455dfecf96Smrg case N_BIGNUM: 21465dfecf96Smrg mpi_xor(RBI(real), RBI(real), OBI(obj)); 21475dfecf96Smrg rbi_canonicalize(real); 21485dfecf96Smrg break; 21495dfecf96Smrg } 21505dfecf96Smrg break; 21515dfecf96Smrg default: 21525dfecf96Smrg fatal_object_error(obj, NOT_AN_INTEGER); 21535dfecf96Smrg break; 21545dfecf96Smrg } 21555dfecf96Smrg} 21565dfecf96Smrg 21575dfecf96Smrg 21585dfecf96Smrg/************************************************************************ 21595dfecf96Smrg * DIVIDE 21605dfecf96Smrg ************************************************************************/ 21615dfecf96Smrgstatic void 21625dfecf96Smrgdivide_number_object(n_number *num, LispObj *obj, int fun, int flo) 21635dfecf96Smrg{ 21645dfecf96Smrg switch (OBJECT_TYPE(obj)) { 21655dfecf96Smrg case LispFixnum_t: 21665dfecf96Smrg switch (NRTYPE(num)) { 21675dfecf96Smrg case N_FIXNUM: 21685dfecf96Smrg ndivide_fi_fi(num, OFI(obj), fun, flo); 21695dfecf96Smrg break; 21705dfecf96Smrg case N_BIGNUM: 21715dfecf96Smrg ndivide_xi_xi(num, obj, fun, flo); 21725dfecf96Smrg break; 21735dfecf96Smrg case N_FLONUM: 21745dfecf96Smrg ndivide_flonum(num, NRFF(num), (double)OFI(obj), fun, flo); 21755dfecf96Smrg break; 21765dfecf96Smrg case N_FIXRATIO: 21775dfecf96Smrg case N_BIGRATIO: 21785dfecf96Smrg ndivide_xr_xi(num, obj, fun, flo); 21795dfecf96Smrg break; 21805dfecf96Smrg } 21815dfecf96Smrg break; 21825dfecf96Smrg case LispInteger_t: 21835dfecf96Smrg switch (NRTYPE(num)) { 21845dfecf96Smrg case N_FIXNUM: 21855dfecf96Smrg ndivide_fi_fi(num, OII(obj), fun, flo); 21865dfecf96Smrg break; 21875dfecf96Smrg case N_BIGNUM: 21885dfecf96Smrg ndivide_xi_xi(num, obj, fun, flo); 21895dfecf96Smrg break; 21905dfecf96Smrg case N_FLONUM: 21915dfecf96Smrg ndivide_flonum(num, NRFF(num), (double)OII(obj), fun, flo); 21925dfecf96Smrg break; 21935dfecf96Smrg case N_FIXRATIO: 21945dfecf96Smrg case N_BIGRATIO: 21955dfecf96Smrg ndivide_xr_xi(num, obj, fun, flo); 21965dfecf96Smrg break; 21975dfecf96Smrg } 21985dfecf96Smrg break; 21995dfecf96Smrg case LispBignum_t: 22005dfecf96Smrg switch (NRTYPE(num)) { 22015dfecf96Smrg case N_FIXNUM: 22025dfecf96Smrg case N_BIGNUM: 22035dfecf96Smrg ndivide_xi_xi(num, obj, fun, flo); 22045dfecf96Smrg break; 22055dfecf96Smrg case N_FLONUM: 22065dfecf96Smrg ndivide_flonum(num, NRFF(num), bi_getd(OBI(obj)), 22075dfecf96Smrg fun, flo); 22085dfecf96Smrg break; 22095dfecf96Smrg case N_FIXRATIO: 22105dfecf96Smrg case N_BIGRATIO: 22115dfecf96Smrg ndivide_xr_xi(num, obj, fun, flo); 22125dfecf96Smrg break; 22135dfecf96Smrg } 22145dfecf96Smrg break; 22155dfecf96Smrg case LispDFloat_t: 22165dfecf96Smrg switch (NRTYPE(num)) { 22175dfecf96Smrg case N_FIXNUM: 22185dfecf96Smrg ndivide_flonum(num, (double)NRFI(num), ODF(obj), 22195dfecf96Smrg fun, flo); 22205dfecf96Smrg break; 22215dfecf96Smrg case N_BIGNUM: 22225dfecf96Smrg ndivide_flonum(num, bi_getd(NRBI(num)), ODF(obj), 22235dfecf96Smrg fun, flo); 22245dfecf96Smrg break; 22255dfecf96Smrg case N_FLONUM: 22265dfecf96Smrg ndivide_flonum(num, NRFF(num), ODF(obj), fun, flo); 22275dfecf96Smrg break; 22285dfecf96Smrg case N_FIXRATIO: 22295dfecf96Smrg ndivide_flonum(num, 22305dfecf96Smrg (double)NRFRN(num) / (double)NRFRD(num), 22315dfecf96Smrg ODF(obj), fun, flo); 22325dfecf96Smrg break; 22335dfecf96Smrg case N_BIGRATIO: 22345dfecf96Smrg ndivide_flonum(num, br_getd(NRBR(num)), ODF(obj), 22355dfecf96Smrg fun, flo); 22365dfecf96Smrg break; 22375dfecf96Smrg } 22385dfecf96Smrg break; 22395dfecf96Smrg case LispRatio_t: 22405dfecf96Smrg switch (NRTYPE(num)) { 22415dfecf96Smrg case N_FIXNUM: 22425dfecf96Smrg case N_BIGNUM: 22435dfecf96Smrg ndivide_xi_xr(num, obj, fun, flo); 22445dfecf96Smrg break; 22455dfecf96Smrg case N_FLONUM: 22465dfecf96Smrg ndivide_flonum(num, NRFF(num), 22475dfecf96Smrg (double)OFRN(obj) / (double)OFRD(obj), 22485dfecf96Smrg fun, flo); 22495dfecf96Smrg break; 22505dfecf96Smrg case N_FIXRATIO: 22515dfecf96Smrg case N_BIGRATIO: 22525dfecf96Smrg ndivide_xr_xr(num, obj, fun, flo); 22535dfecf96Smrg break; 22545dfecf96Smrg } 22555dfecf96Smrg break; 22565dfecf96Smrg case LispBigratio_t: 22575dfecf96Smrg switch (NRTYPE(num)) { 22585dfecf96Smrg case N_FIXNUM: 22595dfecf96Smrg case N_BIGNUM: 22605dfecf96Smrg ndivide_xi_xr(num, obj, fun, flo); 22615dfecf96Smrg break; 22625dfecf96Smrg case N_FLONUM: 22635dfecf96Smrg ndivide_flonum(num, NRFF(num), br_getd(OBR(obj)), 22645dfecf96Smrg fun, flo); 22655dfecf96Smrg break; 22665dfecf96Smrg case N_FIXRATIO: 22675dfecf96Smrg case N_BIGRATIO: 22685dfecf96Smrg ndivide_xr_xr(num, obj, fun, flo); 22695dfecf96Smrg break; 22705dfecf96Smrg } 22715dfecf96Smrg break; 22725dfecf96Smrg default: 22735dfecf96Smrg fatal_object_error(obj, NOT_A_REAL_NUMBER); 22745dfecf96Smrg break; 22755dfecf96Smrg } 22765dfecf96Smrg} 22775dfecf96Smrg 22785dfecf96Smrg 22795dfecf96Smrg/************************************************************************ 22805dfecf96Smrg * COMPARE 22815dfecf96Smrg ************************************************************************/ 22825dfecf96Smrgstatic int 22835dfecf96Smrgcmp_real_real(n_real *op1, n_real *op2) 22845dfecf96Smrg{ 22855dfecf96Smrg switch (RTYPE(op1)) { 22865dfecf96Smrg case N_FIXNUM: 22875dfecf96Smrg switch (RTYPE(op2)) { 22885dfecf96Smrg case N_FIXNUM: 22895dfecf96Smrg return (cmp_fi_fi(RFI(op1), RFI(op2))); 22905dfecf96Smrg case N_BIGNUM: 22915dfecf96Smrg return (cmp_fi_bi(RFI(op1), RBI(op2))); 22925dfecf96Smrg case N_FLONUM: 22935dfecf96Smrg return (cmp_flonum((double)RFI(op1), RFF(op2))); 22945dfecf96Smrg case N_FIXRATIO: 22955dfecf96Smrg return (cmp_fi_fr(RFI(op1), RFRN(op2), RFRD(op2))); 22965dfecf96Smrg case N_BIGRATIO: 22975dfecf96Smrg return (cmp_fi_br(RFI(op1), RBR(op2))); 22985dfecf96Smrg } 22995dfecf96Smrg break; 23005dfecf96Smrg case N_BIGNUM: 23015dfecf96Smrg switch (RTYPE(op2)) { 23025dfecf96Smrg case N_FIXNUM: 23035dfecf96Smrg return (cmp_bi_fi(RBI(op1), RFI(op2))); 23045dfecf96Smrg case N_BIGNUM: 23055dfecf96Smrg return (cmp_bi_bi(RBI(op1), RBI(op2))); 23065dfecf96Smrg case N_FLONUM: 23075dfecf96Smrg return (cmp_flonum(bi_getd(RBI(op1)), RFF(op2))); 23085dfecf96Smrg case N_FIXRATIO: 23095dfecf96Smrg return (cmp_bi_fr(RBI(op1), RFRN(op2), RFRD(op2))); 23105dfecf96Smrg case N_BIGRATIO: 23115dfecf96Smrg return (cmp_bi_br(RBI(op1), RBR(op2))); 23125dfecf96Smrg } 23135dfecf96Smrg break; 23145dfecf96Smrg case N_FLONUM: 23155dfecf96Smrg switch (RTYPE(op2)) { 23165dfecf96Smrg case N_FIXNUM: 23175dfecf96Smrg return (cmp_flonum(RFF(op1), (double)RFI(op2))); 23185dfecf96Smrg case N_BIGNUM: 23195dfecf96Smrg return (cmp_flonum(RFF(op1), bi_getd(RBI(op2)))); 23205dfecf96Smrg case N_FLONUM: 23215dfecf96Smrg return (cmp_flonum(RFF(op1), RFF(op2))); 23225dfecf96Smrg case N_FIXRATIO: 23235dfecf96Smrg return (cmp_flonum(RFF(op1), 23245dfecf96Smrg (double)RFRN(op2) / (double)RFRD(op2))); 23255dfecf96Smrg case N_BIGRATIO: 23265dfecf96Smrg return (cmp_flonum(RFF(op1), br_getd(RBR(op2)))); 23275dfecf96Smrg } 23285dfecf96Smrg break; 23295dfecf96Smrg case N_FIXRATIO: 23305dfecf96Smrg switch (RTYPE(op2)) { 23315dfecf96Smrg case N_FIXNUM: 23325dfecf96Smrg return (cmp_fr_fi(RFRN(op1), RFRD(op1), RFI(op2))); 23335dfecf96Smrg case N_BIGNUM: 23345dfecf96Smrg return (cmp_fr_bi(RFRN(op1), RFRD(op1), RBI(op2))); 23355dfecf96Smrg case N_FLONUM: 23365dfecf96Smrg return (cmp_flonum((double)RFRN(op1) / (double)RFRD(op1), 23375dfecf96Smrg RFF(op2))); 23385dfecf96Smrg case N_FIXRATIO: 23395dfecf96Smrg return (cmp_fr_fr(RFRN(op1), RFRD(op1), 23405dfecf96Smrg RFRN(op2), RFRD(op2))); 23415dfecf96Smrg case N_BIGRATIO: 23425dfecf96Smrg return (cmp_fr_br(RFRN(op1), RFRD(op1), RBR(op2))); 23435dfecf96Smrg } 23445dfecf96Smrg break; 23455dfecf96Smrg case N_BIGRATIO: 23465dfecf96Smrg switch (RTYPE(op2)) { 23475dfecf96Smrg case N_FIXNUM: 23485dfecf96Smrg return (cmp_br_fi(RBR(op1), RFI(op2))); 23495dfecf96Smrg case N_BIGNUM: 23505dfecf96Smrg return (cmp_br_bi(RBR(op1), RBI(op2))); 23515dfecf96Smrg case N_FLONUM: 23525dfecf96Smrg return (cmp_flonum(br_getd(RBR(op1)), RFF(op2))); 23535dfecf96Smrg case N_FIXRATIO: 23545dfecf96Smrg return (cmp_br_fr(RBR(op1), RFRN(op2), RFRD(op2))); 23555dfecf96Smrg case N_BIGRATIO: 23565dfecf96Smrg return (cmp_br_br(RBR(op1), RBR(op2))); 23575dfecf96Smrg } 23585dfecf96Smrg } 23595dfecf96Smrg 23605dfecf96Smrg return (0); 23615dfecf96Smrg} 23625dfecf96Smrg 23635dfecf96Smrgstatic int 23645dfecf96Smrgcmp_real_object(n_real *op1, LispObj *op2) 23655dfecf96Smrg{ 23665dfecf96Smrg switch (OBJECT_TYPE(op2)) { 23675dfecf96Smrg case LispFixnum_t: 23685dfecf96Smrg switch (RTYPE(op1)) { 23695dfecf96Smrg case N_FIXNUM: 23705dfecf96Smrg return (cmp_fi_fi(RFI(op1), OFI(op2))); 23715dfecf96Smrg case N_BIGNUM: 23725dfecf96Smrg return (cmp_bi_fi(RBI(op1), OFI(op2))); 23735dfecf96Smrg case N_FLONUM: 23745dfecf96Smrg return (cmp_flonum(RFF(op1), (double)OFI(op2))); 23755dfecf96Smrg case N_FIXRATIO: 23765dfecf96Smrg return (cmp_fr_fi(RFRD(op1), RFRN(op1), OFI(op2))); 23775dfecf96Smrg case N_BIGRATIO: 23785dfecf96Smrg return (cmp_br_fi(RBR(op1), OFI(op2))); 23795dfecf96Smrg } 23805dfecf96Smrg break; 23815dfecf96Smrg case LispInteger_t: 23825dfecf96Smrg switch (RTYPE(op1)) { 23835dfecf96Smrg case N_FIXNUM: 23845dfecf96Smrg return (cmp_fi_fi(RFI(op1), OII(op2))); 23855dfecf96Smrg case N_BIGNUM: 23865dfecf96Smrg return (cmp_bi_fi(RBI(op1), OII(op2))); 23875dfecf96Smrg case N_FLONUM: 23885dfecf96Smrg return (cmp_flonum(RFF(op1), (double)OII(op2))); 23895dfecf96Smrg case N_FIXRATIO: 23905dfecf96Smrg return (cmp_fr_fi(RFRD(op1), RFRN(op1), OII(op2))); 23915dfecf96Smrg case N_BIGRATIO: 23925dfecf96Smrg return (cmp_br_fi(RBR(op1), OII(op2))); 23935dfecf96Smrg } 23945dfecf96Smrg break; 23955dfecf96Smrg case LispBignum_t: 23965dfecf96Smrg switch (RTYPE(op1)) { 23975dfecf96Smrg case N_FIXNUM: 23985dfecf96Smrg return (cmp_fi_bi(RFI(op1), OBI(op2))); 23995dfecf96Smrg case N_BIGNUM: 24005dfecf96Smrg return (cmp_bi_bi(RBI(op1), OBI(op2))); 24015dfecf96Smrg case N_FLONUM: 24025dfecf96Smrg return (cmp_flonum(RFF(op1), bi_getd(OBI(op2)))); 24035dfecf96Smrg case N_FIXRATIO: 24045dfecf96Smrg return (cmp_fr_bi(RFRD(op1), RFRN(op1), OBI(op2))); 24055dfecf96Smrg case N_BIGRATIO: 24065dfecf96Smrg return (cmp_br_bi(RBR(op1), OBI(op2))); 24075dfecf96Smrg } 24085dfecf96Smrg break; 24095dfecf96Smrg case LispDFloat_t: 24105dfecf96Smrg switch (RTYPE(op1)) { 24115dfecf96Smrg case N_FIXNUM: 24125dfecf96Smrg return (cmp_flonum((double)RFI(op1), ODF(op2))); 24135dfecf96Smrg case N_BIGNUM: 24145dfecf96Smrg return (cmp_flonum(bi_getd(RBI(op1)), ODF(op2))); 24155dfecf96Smrg case N_FLONUM: 24165dfecf96Smrg return (cmp_flonum(RFF(op1), ODF(op2))); 24175dfecf96Smrg case N_FIXRATIO: 24185dfecf96Smrg return (cmp_flonum((double)RFRN(op1) / (double)RFRD(op1), 24195dfecf96Smrg ODF(op2))); 24205dfecf96Smrg case N_BIGRATIO: 24215dfecf96Smrg return (cmp_flonum(br_getd(RBR(op1)), ODF(op2))); 24225dfecf96Smrg } 24235dfecf96Smrg break; 24245dfecf96Smrg case LispRatio_t: 24255dfecf96Smrg switch (RTYPE(op1)) { 24265dfecf96Smrg case N_FIXNUM: 24275dfecf96Smrg return (cmp_fi_fr(RFI(op1), OFRN(op2), OFRD(op2))); 24285dfecf96Smrg case N_BIGNUM: 24295dfecf96Smrg return (cmp_bi_fr(RBI(op1), OFRN(op2), OFRD(op2))); 24305dfecf96Smrg case N_FLONUM: 24315dfecf96Smrg return (cmp_flonum(RFF(op1), 24325dfecf96Smrg (double)OFRN(op2) / (double)OFRD(op2))); 24335dfecf96Smrg case N_FIXRATIO: 24345dfecf96Smrg return (cmp_fr_fr(RFRN(op1), RFRD(op1), 24355dfecf96Smrg OFRN(op2), OFRD(op2))); 24365dfecf96Smrg case N_BIGRATIO: 24375dfecf96Smrg return (cmp_br_fr(RBR(op1), OFRN(op2), OFRD(op2))); 24385dfecf96Smrg } 24395dfecf96Smrg break; 24405dfecf96Smrg case LispBigratio_t: 24415dfecf96Smrg switch (RTYPE(op1)) { 24425dfecf96Smrg case N_FIXNUM: 24435dfecf96Smrg return (cmp_fi_br(RFI(op1), OBR(op2))); 24445dfecf96Smrg case N_BIGNUM: 24455dfecf96Smrg return (cmp_bi_br(RBI(op1), OBR(op2))); 24465dfecf96Smrg case N_FLONUM: 24475dfecf96Smrg return (cmp_flonum(RFF(op1), br_getd(OBR(op2)))); 24485dfecf96Smrg case N_FIXRATIO: 24495dfecf96Smrg return (cmp_fr_br(RFRN(op1), RFRD(op1), OBR(op2))); 24505dfecf96Smrg case N_BIGRATIO: 24515dfecf96Smrg return (cmp_br_br(RBR(op1), OBR(op2))); 24525dfecf96Smrg } 24535dfecf96Smrg break; 24545dfecf96Smrg default: 24555dfecf96Smrg fatal_object_error(op2, NOT_A_REAL_NUMBER); 24565dfecf96Smrg break; 24575dfecf96Smrg } 24585dfecf96Smrg 24595dfecf96Smrg return (0); 24605dfecf96Smrg} 24615dfecf96Smrg 24625dfecf96Smrg#if 0 /* not used */ 24635dfecf96Smrgstatic int 24645dfecf96Smrgcmp_number_object(n_number *op1, LispObj *op2) 24655dfecf96Smrg{ 24665dfecf96Smrg if (op1->complex) { 24675dfecf96Smrg if (OBJECT_TYPE(op2) == LispComplex_t) { 24685dfecf96Smrg if (cmp_real_object(NREAL(op1), OCXR(op2)) == 0) 24695dfecf96Smrg return (cmp_real_object(NIMAG(op1), OCXI(op2))); 24705dfecf96Smrg return (1); 24715dfecf96Smrg } 24725dfecf96Smrg else if (cmp_real_real(NIMAG(op1), &zero) == 0) 24735dfecf96Smrg return (cmp_real_object(NREAL(op1), op2)); 24745dfecf96Smrg else 24755dfecf96Smrg return (1); 24765dfecf96Smrg } 24775dfecf96Smrg else { 24785dfecf96Smrg switch (OBJECT_TYPE(op2)) { 24795dfecf96Smrg case LispFixnum_t: 24805dfecf96Smrg switch (NRTYPE(op1)) { 24815dfecf96Smrg case N_FIXNUM: 24825dfecf96Smrg return (cmp_fi_fi(NRFI(op1), OFI(op2))); 24835dfecf96Smrg case N_BIGNUM: 24845dfecf96Smrg return (cmp_bi_fi(NRBI(op1), OFI(op2))); 24855dfecf96Smrg case N_FLONUM: 24865dfecf96Smrg return (cmp_flonum(NRFF(op1), (double)OFI(op2))); 24875dfecf96Smrg case N_FIXRATIO: 24885dfecf96Smrg return (cmp_fr_fi(NRFRD(op1), NRFRN(op1), OFI(op2))); 24895dfecf96Smrg case N_BIGRATIO: 24905dfecf96Smrg return (cmp_br_fi(NRBR(op1), OFI(op2))); 24915dfecf96Smrg } 24925dfecf96Smrg break; 24935dfecf96Smrg case LispInteger_t: 24945dfecf96Smrg switch (NRTYPE(op1)) { 24955dfecf96Smrg case N_FIXNUM: 24965dfecf96Smrg return (cmp_fi_fi(NRFI(op1), OII(op2))); 24975dfecf96Smrg case N_BIGNUM: 24985dfecf96Smrg return (cmp_bi_fi(NRBI(op1), OII(op2))); 24995dfecf96Smrg case N_FLONUM: 25005dfecf96Smrg return (cmp_flonum(NRFF(op1), (double)OII(op2))); 25015dfecf96Smrg case N_FIXRATIO: 25025dfecf96Smrg return (cmp_fr_fi(NRFRD(op1), NRFRN(op1), OII(op2))); 25035dfecf96Smrg case N_BIGRATIO: 25045dfecf96Smrg return (cmp_br_fi(NRBR(op1), OII(op2))); 25055dfecf96Smrg } 25065dfecf96Smrg break; 25075dfecf96Smrg case LispBignum_t: 25085dfecf96Smrg switch (NRTYPE(op1)) { 25095dfecf96Smrg case N_FIXNUM: 25105dfecf96Smrg return (cmp_fi_bi(NRFI(op1), OBI(op2))); 25115dfecf96Smrg case N_BIGNUM: 25125dfecf96Smrg return (cmp_bi_bi(NRBI(op1), OBI(op2))); 25135dfecf96Smrg case N_FLONUM: 25145dfecf96Smrg return (cmp_flonum(NRFF(op1), bi_getd(OBI(op2)))); 25155dfecf96Smrg case N_FIXRATIO: 25165dfecf96Smrg return (cmp_fr_bi(NRFRD(op1), NRFRN(op1), OBI(op2))); 25175dfecf96Smrg case N_BIGRATIO: 25185dfecf96Smrg return (cmp_br_bi(NRBR(op1), OBI(op2))); 25195dfecf96Smrg } 25205dfecf96Smrg break; 25215dfecf96Smrg case LispDFloat_t: 25225dfecf96Smrg switch (NRTYPE(op1)) { 25235dfecf96Smrg case N_FIXNUM: 25245dfecf96Smrg return (cmp_flonum((double)NRFI(op1), ODF(op2))); 25255dfecf96Smrg case N_BIGNUM: 25265dfecf96Smrg return (cmp_flonum(bi_getd(NRBI(op1)), ODF(op2))); 25275dfecf96Smrg case N_FLONUM: 25285dfecf96Smrg return (cmp_flonum(NRFF(op1), ODF(op2))); 25295dfecf96Smrg case N_FIXRATIO: 25305dfecf96Smrg return (cmp_flonum((double)NRFRN(op1) / 25315dfecf96Smrg (double)NRFRD(op1), 25325dfecf96Smrg ODF(op2))); 25335dfecf96Smrg case N_BIGRATIO: 25345dfecf96Smrg return (cmp_flonum(br_getd(NRBR(op1)), ODF(op2))); 25355dfecf96Smrg } 25365dfecf96Smrg break; 25375dfecf96Smrg case LispRatio_t: 25385dfecf96Smrg switch (NRTYPE(op1)) { 25395dfecf96Smrg case N_FIXNUM: 25405dfecf96Smrg return (cmp_fi_fr(NRFI(op1), OFRN(op2), OFRD(op2))); 25415dfecf96Smrg case N_BIGNUM: 25425dfecf96Smrg return (cmp_bi_fr(NRBI(op1), OFRN(op2), OFRD(op2))); 25435dfecf96Smrg case N_FLONUM: 25445dfecf96Smrg return (cmp_flonum(NRFF(op1), 25455dfecf96Smrg (double)OFRN(op2) / (double)OFRD(op2))); 25465dfecf96Smrg case N_FIXRATIO: 25475dfecf96Smrg return (cmp_fr_fr(NRFRN(op1), NRFRD(op1), 25485dfecf96Smrg OFRN(op2), OFRD(op2))); 25495dfecf96Smrg case N_BIGRATIO: 25505dfecf96Smrg return (cmp_br_fr(NRBR(op1), OFRN(op2), OFRD(op2))); 25515dfecf96Smrg } 25525dfecf96Smrg break; 25535dfecf96Smrg case LispBigratio_t: 25545dfecf96Smrg switch (NRTYPE(op1)) { 25555dfecf96Smrg case N_FIXNUM: 25565dfecf96Smrg return (cmp_fi_br(NRFI(op1), OBR(op2))); 25575dfecf96Smrg case N_BIGNUM: 25585dfecf96Smrg return (cmp_bi_br(NRBI(op1), OBR(op2))); 25595dfecf96Smrg case N_FLONUM: 25605dfecf96Smrg return (cmp_flonum(NRFF(op1), br_getd(OBR(op2)))); 25615dfecf96Smrg case N_FIXRATIO: 25625dfecf96Smrg return (cmp_fr_br(NRFRN(op1), NRFRD(op1), OBR(op2))); 25635dfecf96Smrg case N_BIGRATIO: 25645dfecf96Smrg return (cmp_br_br(NRBR(op1), OBR(op2))); 25655dfecf96Smrg } 25665dfecf96Smrg break; 25675dfecf96Smrg case LispComplex_t: 25685dfecf96Smrg if (cmp_real_object(&zero, OCXI(op2)) == 0) 25695dfecf96Smrg return (cmp_real_object(NREAL(op1), OCXR(op2))); 25705dfecf96Smrg return (1); 25715dfecf96Smrg default: 25725dfecf96Smrg fatal_object_error(op2, NOT_A_NUMBER); 25735dfecf96Smrg break; 25745dfecf96Smrg } 25755dfecf96Smrg } 25765dfecf96Smrg 25775dfecf96Smrg return (0); 25785dfecf96Smrg} 25795dfecf96Smrg#endif 25805dfecf96Smrg 25815dfecf96Smrgstatic int 25825dfecf96Smrgcmp_object_object(LispObj *op1, LispObj *op2, int real) 25835dfecf96Smrg{ 25845dfecf96Smrg if (OBJECT_TYPE(op1) == LispComplex_t) { 25855dfecf96Smrg if (real) 25865dfecf96Smrg fatal_object_error(op1, NOT_A_REAL_NUMBER); 25875dfecf96Smrg if (OBJECT_TYPE(op2) == LispComplex_t) 25885dfecf96Smrg return (cmp_cx_cx(op1, op2)); 25895dfecf96Smrg else if (cmp_real_object(&zero, OCXI(op1)) == 0) 25905dfecf96Smrg return (cmp_object_object(OCXR(op1), op2, real)); 25915dfecf96Smrg return (1); 25925dfecf96Smrg } 25935dfecf96Smrg else if (OBJECT_TYPE(op2) == LispComplex_t) { 25945dfecf96Smrg if (real) 25955dfecf96Smrg fatal_object_error(op1, NOT_A_REAL_NUMBER); 25965dfecf96Smrg if (cmp_real_object(&zero, OCXI(op2)) == 0) 25975dfecf96Smrg return (cmp_object_object(op1, OCXR(op2), real)); 25985dfecf96Smrg return (1); 25995dfecf96Smrg } 26005dfecf96Smrg else { 26015dfecf96Smrg switch (OBJECT_TYPE(op1)) { 26025dfecf96Smrg case LispFixnum_t: 26035dfecf96Smrg switch (OBJECT_TYPE(op2)) { 26045dfecf96Smrg case LispFixnum_t: 26055dfecf96Smrg return (cmp_fi_fi(OFI(op1), OFI(op2))); 26065dfecf96Smrg case LispInteger_t: 26075dfecf96Smrg return (cmp_fi_fi(OFI(op1), OII(op2))); 26085dfecf96Smrg case LispBignum_t: 26095dfecf96Smrg return (cmp_fi_bi(OFI(op1), OBI(op2))); 26105dfecf96Smrg case LispDFloat_t: 26115dfecf96Smrg return (cmp_flonum((double)OFI(op1), ODF(op2))); 26125dfecf96Smrg case LispRatio_t: 26135dfecf96Smrg return (cmp_fi_fr(OFI(op1), 26145dfecf96Smrg OFRN(op2), OFRD(op2))); 26155dfecf96Smrg case LispBigratio_t: 26165dfecf96Smrg return (cmp_fi_br(OFI(op1), OBR(op2))); 26175dfecf96Smrg default: 26185dfecf96Smrg break; 26195dfecf96Smrg } 26205dfecf96Smrg break; 26215dfecf96Smrg case LispInteger_t: 26225dfecf96Smrg switch (OBJECT_TYPE(op2)) { 26235dfecf96Smrg case LispFixnum_t: 26245dfecf96Smrg return (cmp_fi_fi(OII(op1), OFI(op2))); 26255dfecf96Smrg case LispInteger_t: 26265dfecf96Smrg return (cmp_fi_fi(OII(op1), OII(op2))); 26275dfecf96Smrg case LispBignum_t: 26285dfecf96Smrg return (cmp_fi_bi(OII(op1), OBI(op2))); 26295dfecf96Smrg case LispDFloat_t: 26305dfecf96Smrg return (cmp_flonum((double)OII(op1), ODF(op2))); 26315dfecf96Smrg case LispRatio_t: 26325dfecf96Smrg return (cmp_fi_fr(OII(op1), 26335dfecf96Smrg OFRN(op2), OFRD(op2))); 26345dfecf96Smrg case LispBigratio_t: 26355dfecf96Smrg return (cmp_fi_br(OII(op1), OBR(op2))); 26365dfecf96Smrg default: 26375dfecf96Smrg break; 26385dfecf96Smrg } 26395dfecf96Smrg break; 26405dfecf96Smrg case LispBignum_t: 26415dfecf96Smrg switch (OBJECT_TYPE(op2)) { 26425dfecf96Smrg case LispFixnum_t: 26435dfecf96Smrg return (cmp_bi_fi(OBI(op1), OFI(op2))); 26445dfecf96Smrg case LispInteger_t: 26455dfecf96Smrg return (cmp_bi_fi(OBI(op1), OII(op2))); 26465dfecf96Smrg case LispBignum_t: 26475dfecf96Smrg return (cmp_bi_bi(OBI(op1), OBI(op2))); 26485dfecf96Smrg case LispDFloat_t: 26495dfecf96Smrg return (cmp_flonum(bi_getd(OBI(op1)), ODF(op2))); 26505dfecf96Smrg case LispRatio_t: 26515dfecf96Smrg return (cmp_bi_fr(OBI(op1), 26525dfecf96Smrg OFRN(op2), OFRD(op2))); 26535dfecf96Smrg case LispBigratio_t: 26545dfecf96Smrg return (cmp_bi_br(OBI(op1), OBR(op2))); 26555dfecf96Smrg default: 26565dfecf96Smrg break; 26575dfecf96Smrg } 26585dfecf96Smrg break; 26595dfecf96Smrg case LispDFloat_t: 26605dfecf96Smrg switch (OBJECT_TYPE(op2)) { 26615dfecf96Smrg case LispFixnum_t: 26625dfecf96Smrg return (cmp_flonum(ODF(op1), (double)OFI(op2))); 26635dfecf96Smrg case LispInteger_t: 26645dfecf96Smrg return (cmp_flonum(ODF(op1), (double)OII(op2))); 26655dfecf96Smrg case LispBignum_t: 26665dfecf96Smrg return (cmp_flonum(ODF(op1), bi_getd(OBI(op2)))); 26675dfecf96Smrg case LispDFloat_t: 26685dfecf96Smrg return (cmp_flonum(ODF(op1), ODF(op2))); 26695dfecf96Smrg break; 26705dfecf96Smrg case LispRatio_t: 26715dfecf96Smrg return (cmp_flonum(ODF(op1), 26725dfecf96Smrg (double)OFRN(op2) / 26735dfecf96Smrg (double)OFRD(op2))); 26745dfecf96Smrg case LispBigratio_t: 26755dfecf96Smrg return (cmp_flonum(ODF(op1), br_getd(OBR(op2)))); 26765dfecf96Smrg default: 26775dfecf96Smrg break; 26785dfecf96Smrg } 26795dfecf96Smrg break; 26805dfecf96Smrg case LispRatio_t: 26815dfecf96Smrg switch (OBJECT_TYPE(op2)) { 26825dfecf96Smrg case LispFixnum_t: 26835dfecf96Smrg return (cmp_fr_fi(OFRN(op1), OFRD(op1), OFI(op2))); 26845dfecf96Smrg case LispInteger_t: 26855dfecf96Smrg return (cmp_fr_fi(OFRN(op1), OFRD(op1), OII(op2))); 26865dfecf96Smrg case LispBignum_t: 26875dfecf96Smrg return (cmp_fr_bi(OFRN(op1), OFRD(op1), OBI(op2))); 26885dfecf96Smrg case LispDFloat_t: 26895dfecf96Smrg return (cmp_flonum((double)OFRN(op1) / 26905dfecf96Smrg (double)OFRD(op1), 26915dfecf96Smrg ODF(op2))); 26925dfecf96Smrg case LispRatio_t: 26935dfecf96Smrg return (cmp_fr_fr(OFRN(op1), OFRD(op1), 26945dfecf96Smrg OFRN(op2), OFRD(op2))); 26955dfecf96Smrg case LispBigratio_t: 26965dfecf96Smrg return (cmp_fr_br(OFRN(op1), OFRD(op1), OBR(op2))); 26975dfecf96Smrg default: 26985dfecf96Smrg break; 26995dfecf96Smrg } 27005dfecf96Smrg break; 27015dfecf96Smrg case LispBigratio_t: 27025dfecf96Smrg switch (OBJECT_TYPE(op2)) { 27035dfecf96Smrg case LispFixnum_t: 27045dfecf96Smrg return (cmp_br_fi(OBR(op1), OFI(op2))); 27055dfecf96Smrg case LispInteger_t: 27065dfecf96Smrg return (cmp_br_fi(OBR(op1), OII(op2))); 27075dfecf96Smrg case LispBignum_t: 27085dfecf96Smrg return (cmp_br_bi(OBR(op1), OBI(op2))); 27095dfecf96Smrg case LispDFloat_t: 27105dfecf96Smrg return (cmp_flonum(br_getd(OBR(op1)), ODF(op2))); 27115dfecf96Smrg case LispRatio_t: 27125dfecf96Smrg return (cmp_br_fr(OBR(op1), OFRN(op2), OFRD(op2))); 27135dfecf96Smrg case LispBigratio_t: 27145dfecf96Smrg return (cmp_br_br(OBR(op1), OBR(op2))); 27155dfecf96Smrg default: 27165dfecf96Smrg break; 27175dfecf96Smrg } 27185dfecf96Smrg break; 27195dfecf96Smrg default: 27205dfecf96Smrg fatal_object_error(op1, NOT_A_NUMBER); 27215dfecf96Smrg break; 27225dfecf96Smrg } 27235dfecf96Smrg } 27245dfecf96Smrg 27255dfecf96Smrg fatal_object_error(op2, NOT_A_NUMBER); 27265dfecf96Smrg return (0); 27275dfecf96Smrg} 27285dfecf96Smrg 27295dfecf96Smrg 27305dfecf96Smrg/************************************************************************ 27315dfecf96Smrg * FIXNUM 27325dfecf96Smrg ************************************************************************/ 27335dfecf96Smrg/* 27345dfecf96Smrg * check if op1 + op2 will overflow 27355dfecf96Smrg */ 27365dfecf96Smrgstatic INLINE int 27375dfecf96Smrgfi_fi_add_overflow(long op1, long op2) 27385dfecf96Smrg{ 27395dfecf96Smrg long op = op1 + op2; 27405dfecf96Smrg 27415dfecf96Smrg return (op1 > 0 ? op2 > op : op2 < op); 27425dfecf96Smrg} 27435dfecf96Smrg 27445dfecf96Smrg/* 27455dfecf96Smrg * check if op1 - op2 will overflow 27465dfecf96Smrg */ 27475dfecf96Smrgstatic INLINE int 27485dfecf96Smrgfi_fi_sub_overflow(long op1, long op2) 27495dfecf96Smrg{ 27505dfecf96Smrg long op = op1 - op2; 27515dfecf96Smrg 27525dfecf96Smrg return (((op1 < 0) ^ (op2 < 0)) && ((op < 0) ^ (op1 < 0))); 27535dfecf96Smrg} 27545dfecf96Smrg 27555dfecf96Smrg/* 27565dfecf96Smrg * check if op1 * op2 will overflow 27575dfecf96Smrg */ 27585dfecf96Smrgstatic INLINE int 27595dfecf96Smrgfi_fi_mul_overflow(long op1, long op2) 27605dfecf96Smrg{ 27615dfecf96Smrg#ifndef LONG64 27625dfecf96Smrg double op = (double)op1 * (double)op2; 27635dfecf96Smrg 27645dfecf96Smrg return (op > 2147483647.0 || op < -2147483648.0); 27655dfecf96Smrg#else 27665dfecf96Smrg int shift; 27675dfecf96Smrg long mask; 27685dfecf96Smrg 27695dfecf96Smrg if (op1 == 0 || op1 == 1 || op2 == 0 || op2 == 1) 27705dfecf96Smrg return (0); 27715dfecf96Smrg 27725dfecf96Smrg if (op1 == MINSLONG || op2 == MINSLONG) 27735dfecf96Smrg return (1); 27745dfecf96Smrg 27755dfecf96Smrg if (op1 < 0) 27765dfecf96Smrg op1 = -op1; 27775dfecf96Smrg if (op2 < 0) 27785dfecf96Smrg op2 = -op2; 27795dfecf96Smrg 27805dfecf96Smrg for (shift = 0, mask = FI_MASK; shift < LONGSBITS; shift++, mask >>= 1) 27815dfecf96Smrg if (op1 & mask) 27825dfecf96Smrg break; 27835dfecf96Smrg ++shift; 27845dfecf96Smrg for (mask = FI_MASK; shift < LONGSBITS; shift++, mask >>= 1) 27855dfecf96Smrg if (op2 & mask) 27865dfecf96Smrg break; 27875dfecf96Smrg 27885dfecf96Smrg return (shift < LONGSBITS); 27895dfecf96Smrg#endif 27905dfecf96Smrg} 27915dfecf96Smrg 27925dfecf96Smrg 27935dfecf96Smrg/************************************************************************ 27945dfecf96Smrg * BIGNUM 27955dfecf96Smrg ************************************************************************/ 27965dfecf96Smrgstatic void 27975dfecf96Smrgrbi_canonicalize(n_real *real) 27985dfecf96Smrg{ 27995dfecf96Smrg if (mpi_fiti(RBI(real))) { 28005dfecf96Smrg long fi = mpi_geti(RBI(real)); 28015dfecf96Smrg 28025dfecf96Smrg RTYPE(real) = N_FIXNUM; 28035dfecf96Smrg mpi_clear(RBI(real)); 28045dfecf96Smrg XFREE(RBI(real)); 28055dfecf96Smrg RFI(real) = fi; 28065dfecf96Smrg } 28075dfecf96Smrg} 28085dfecf96Smrg 28095dfecf96Smrg 28105dfecf96Smrg/************************************************************************ 28115dfecf96Smrg * RATIO 28125dfecf96Smrg ************************************************************************/ 28135dfecf96Smrgstatic void 28145dfecf96Smrgrfr_canonicalize(n_real *real) 28155dfecf96Smrg{ 28165dfecf96Smrg long num, numerator, den, denominator, rest; 28175dfecf96Smrg 28185dfecf96Smrg num = numerator = RFRN(real); 28195dfecf96Smrg den = denominator = RFRD(real); 28205dfecf96Smrg if (denominator == 0) 28215dfecf96Smrg fatal_error(DIVIDE_BY_ZERO); 28225dfecf96Smrg 28235dfecf96Smrg if (num == MINSLONG || den == MINSLONG) { 28245dfecf96Smrg mpr *bigratio = XALLOC(mpr); 28255dfecf96Smrg 28265dfecf96Smrg mpr_init(bigratio); 28275dfecf96Smrg mpr_seti(bigratio, num, den); 28285dfecf96Smrg RTYPE(real) = N_BIGRATIO; 28295dfecf96Smrg RBR(real) = bigratio; 28305dfecf96Smrg rbr_canonicalize(real); 28315dfecf96Smrg return; 28325dfecf96Smrg } 28335dfecf96Smrg 28345dfecf96Smrg if (num < 0) 28355dfecf96Smrg num = -num; 28365dfecf96Smrg else if (num == 0) { 28375dfecf96Smrg RFI(real) = 0; 28385dfecf96Smrg RTYPE(real) = N_FIXNUM; 28395dfecf96Smrg return; 28405dfecf96Smrg } 28415dfecf96Smrg for (;;) { 28425dfecf96Smrg if ((rest = den % num) == 0) 28435dfecf96Smrg break; 28445dfecf96Smrg den = num; 28455dfecf96Smrg num = rest; 28465dfecf96Smrg } 28475dfecf96Smrg if (den != 1) { 28485dfecf96Smrg denominator /= num; 28495dfecf96Smrg numerator /= num; 28505dfecf96Smrg } 28515dfecf96Smrg if (denominator < 0) { 28525dfecf96Smrg numerator = -numerator; 28535dfecf96Smrg denominator = -denominator; 28545dfecf96Smrg } 28555dfecf96Smrg if (denominator == 1) { 28565dfecf96Smrg RTYPE(real) = N_FIXNUM; 28575dfecf96Smrg RFI(real) = numerator; 28585dfecf96Smrg } 28595dfecf96Smrg else { 28605dfecf96Smrg RFRN(real) = numerator; 28615dfecf96Smrg RFRD(real) = denominator; 28625dfecf96Smrg } 28635dfecf96Smrg} 28645dfecf96Smrg 28655dfecf96Smrgstatic void 28665dfecf96Smrgrbr_canonicalize(n_real *real) 28675dfecf96Smrg{ 28685dfecf96Smrg int fitnum, fitden; 28695dfecf96Smrg long numerator, denominator; 28705dfecf96Smrg 28715dfecf96Smrg mpr_canonicalize(RBR(real)); 28725dfecf96Smrg fitnum = mpi_fiti(RBRN(real)); 28735dfecf96Smrg fitden = mpi_fiti(RBRD(real)); 28745dfecf96Smrg if (fitnum && fitden) { 28755dfecf96Smrg numerator = mpi_geti(RBRN(real)); 28765dfecf96Smrg denominator = mpi_geti(RBRD(real)); 28775dfecf96Smrg mpr_clear(RBR(real)); 28785dfecf96Smrg XFREE(RBR(real)); 28795dfecf96Smrg if (numerator == 0) { 28805dfecf96Smrg RFI(real) = 0; 28815dfecf96Smrg RTYPE(real) = N_FIXNUM; 28825dfecf96Smrg } 28835dfecf96Smrg else if (denominator == 1) { 28845dfecf96Smrg RTYPE(real) = N_FIXNUM; 28855dfecf96Smrg RFI(real) = numerator; 28865dfecf96Smrg } 28875dfecf96Smrg else { 28885dfecf96Smrg RTYPE(real) = N_FIXRATIO; 28895dfecf96Smrg RFRN(real) = numerator; 28905dfecf96Smrg RFRD(real) = denominator; 28915dfecf96Smrg } 28925dfecf96Smrg } 28935dfecf96Smrg else if (fitden) { 28945dfecf96Smrg denominator = mpi_geti(RBRD(real)); 28955dfecf96Smrg if (denominator == 1) { 28965dfecf96Smrg mpi *bigi = XALLOC(mpi); 28975dfecf96Smrg 28985dfecf96Smrg mpi_init(bigi); 28995dfecf96Smrg mpi_set(bigi, RBRN(real)); 29005dfecf96Smrg mpr_clear(RBR(real)); 29015dfecf96Smrg XFREE(RBR(real)); 29025dfecf96Smrg RTYPE(real) = N_BIGNUM; 29035dfecf96Smrg RBI(real) = bigi; 29045dfecf96Smrg } 29055dfecf96Smrg else if (denominator == 0) 29065dfecf96Smrg fatal_error(DIVIDE_BY_ZERO); 29075dfecf96Smrg } 29085dfecf96Smrg} 29095dfecf96Smrg 29105dfecf96Smrg 29115dfecf96Smrg/************************************************************************ 29125dfecf96Smrg * COMPLEX 29135dfecf96Smrg ************************************************************************/ 29145dfecf96Smrgstatic void 29155dfecf96Smrgncx_canonicalize(n_number *num) 29165dfecf96Smrg{ 29175dfecf96Smrg if (NITYPE(num) == N_FIXNUM && NIFI(num) == 0) 29185dfecf96Smrg num->complex = 0; 29195dfecf96Smrg} 29205dfecf96Smrg 29215dfecf96Smrg 29225dfecf96Smrg/************************************************************************ 29235dfecf96Smrg * DIVIDE 29245dfecf96Smrg ************************************************************************/ 29255dfecf96Smrg#define NDIVIDE_NOP 0 29265dfecf96Smrg#define NDIVIDE_ADD 1 29275dfecf96Smrg#define NDIVIDE_SUB 2 29285dfecf96Smrgstatic void 29295dfecf96Smrgndivide_fi_fi(n_number *num, long div, int fun, int flo) 29305dfecf96Smrg{ 29315dfecf96Smrg long quo, rem; 29325dfecf96Smrg 29335dfecf96Smrg if (NRFI(num) == MINSLONG || div == MINSLONG) { 29345dfecf96Smrg LispObj integer; 29355dfecf96Smrg mpi *bignum = XALLOC(mpi); 29365dfecf96Smrg 29375dfecf96Smrg mpi_init(bignum); 29385dfecf96Smrg mpi_seti(bignum, NRFI(num)); 29395dfecf96Smrg NRBI(num) = bignum; 29405dfecf96Smrg NRTYPE(num) = N_BIGNUM; 29415dfecf96Smrg integer.type = LispInteger_t; 29425dfecf96Smrg integer.data.integer = div; 29435dfecf96Smrg ndivide_xi_xi(num, &integer, fun, flo); 29445dfecf96Smrg return; 29455dfecf96Smrg } 29465dfecf96Smrg else { 29475dfecf96Smrg quo = NRFI(num) / div; 29485dfecf96Smrg rem = NRFI(num) % div; 29495dfecf96Smrg } 29505dfecf96Smrg 29515dfecf96Smrg switch (fun) { 29525dfecf96Smrg case NDIVIDE_CEIL: 29535dfecf96Smrg if ((rem < 0 && div < 0) || (rem > 0 && div > 0)) { 29545dfecf96Smrg ++quo; 29555dfecf96Smrg rem -= div; 29565dfecf96Smrg } 29575dfecf96Smrg break; 29585dfecf96Smrg case NDIVIDE_FLOOR: 29595dfecf96Smrg if ((rem < 0 && div > 0) || (rem > 0 && div < 0)) { 29605dfecf96Smrg --quo; 29615dfecf96Smrg rem += div; 29625dfecf96Smrg } 29635dfecf96Smrg break; 29645dfecf96Smrg case NDIVIDE_ROUND: 29655dfecf96Smrg if (div > 0) { 29665dfecf96Smrg if (rem > 0) { 29675dfecf96Smrg if (rem >= (div + 1) / 2) { 29685dfecf96Smrg ++quo; 29695dfecf96Smrg rem -= div; 29705dfecf96Smrg } 29715dfecf96Smrg } 29725dfecf96Smrg else { 29735dfecf96Smrg if (rem <= (-div - 1) / 2) { 29745dfecf96Smrg --quo; 29755dfecf96Smrg rem += div; 29765dfecf96Smrg } 29775dfecf96Smrg } 29785dfecf96Smrg } 29795dfecf96Smrg else { 29805dfecf96Smrg if (rem > 0) { 29815dfecf96Smrg if (rem >= (-div + 1) / 2) { 29825dfecf96Smrg --quo; 29835dfecf96Smrg rem += div; 29845dfecf96Smrg } 29855dfecf96Smrg } 29865dfecf96Smrg else { 29875dfecf96Smrg if (rem <= (div - 1) / 2) { 29885dfecf96Smrg ++quo; 29895dfecf96Smrg rem -= div; 29905dfecf96Smrg } 29915dfecf96Smrg } 29925dfecf96Smrg } 29935dfecf96Smrg break; 29945dfecf96Smrg } 29955dfecf96Smrg 29965dfecf96Smrg NITYPE(num) = N_FIXNUM; 29975dfecf96Smrg NIFI(num) = rem; 29985dfecf96Smrg if (flo) { 29995dfecf96Smrg NRTYPE(num) = N_FLONUM; 30005dfecf96Smrg NRFF(num) = (double)quo; 30015dfecf96Smrg } 30025dfecf96Smrg else 30035dfecf96Smrg NRFI(num) = quo; 30045dfecf96Smrg} 30055dfecf96Smrg 30065dfecf96Smrgstatic void 30075dfecf96Smrgndivide_xi_xi(n_number *num, LispObj *div, int fun, int flo) 30085dfecf96Smrg{ 30095dfecf96Smrg LispType type = OBJECT_TYPE(div); 30105dfecf96Smrg int state = NDIVIDE_NOP, dsign, rsign; 30115dfecf96Smrg mpi *quo, *rem; 30125dfecf96Smrg 30135dfecf96Smrg quo = XALLOC(mpi); 30145dfecf96Smrg mpi_init(quo); 30155dfecf96Smrg if (NRTYPE(num) == N_FIXNUM) 30165dfecf96Smrg mpi_seti(quo, NRFI(num)); 30175dfecf96Smrg else 30185dfecf96Smrg mpi_set(quo, NRBI(num)); 30195dfecf96Smrg 30205dfecf96Smrg rem = XALLOC(mpi); 30215dfecf96Smrg mpi_init(rem); 30225dfecf96Smrg 30235dfecf96Smrg switch (type) { 30245dfecf96Smrg case LispFixnum_t: 30255dfecf96Smrg mpi_seti(rem, OFI(div)); 30265dfecf96Smrg break; 30275dfecf96Smrg case LispInteger_t: 30285dfecf96Smrg mpi_seti(rem, OII(div)); 30295dfecf96Smrg break; 30305dfecf96Smrg default: 30315dfecf96Smrg mpi_set(rem, OBI(div)); 30325dfecf96Smrg } 30335dfecf96Smrg 30345dfecf96Smrg dsign = mpi_sgn(rem); 30355dfecf96Smrg 30365dfecf96Smrg mpi_divqr(quo, rem, quo, rem); 30375dfecf96Smrg rsign = mpi_sgn(rem); 30385dfecf96Smrg 30395dfecf96Smrg switch (fun) { 30405dfecf96Smrg case NDIVIDE_CEIL: 30415dfecf96Smrg if ((rsign < 0 && dsign < 0) || (rsign > 0 && dsign > 0)) 30425dfecf96Smrg state = NDIVIDE_ADD; 30435dfecf96Smrg break; 30445dfecf96Smrg case NDIVIDE_FLOOR: 30455dfecf96Smrg if ((rsign < 0 && dsign > 0) || (rsign > 0 && dsign < 0)) 30465dfecf96Smrg state = NDIVIDE_SUB; 30475dfecf96Smrg break; 30485dfecf96Smrg case NDIVIDE_ROUND: { 30495dfecf96Smrg mpi test; 30505dfecf96Smrg 30515dfecf96Smrg mpi_init(&test); 30525dfecf96Smrg switch (type) { 30535dfecf96Smrg case LispFixnum_t: 30545dfecf96Smrg mpi_seti(&test, OFI(div)); 30555dfecf96Smrg break; 30565dfecf96Smrg case LispInteger_t: 30575dfecf96Smrg mpi_seti(&test, OII(div)); 30585dfecf96Smrg break; 30595dfecf96Smrg default: 30605dfecf96Smrg mpi_set(&test, OBI(div)); 30615dfecf96Smrg } 30625dfecf96Smrg if (dsign > 0) { 30635dfecf96Smrg if (rsign > 0) { 30645dfecf96Smrg mpi_addi(&test, &test, 1); 30655dfecf96Smrg mpi_divi(&test, &test, 2); 30665dfecf96Smrg if (mpi_cmp(rem, &test) >= 0) 30675dfecf96Smrg state = NDIVIDE_ADD; 30685dfecf96Smrg } 30695dfecf96Smrg else { 30705dfecf96Smrg mpi_neg(&test, &test); 30715dfecf96Smrg mpi_subi(&test, &test, 1); 30725dfecf96Smrg mpi_divi(&test, &test, 2); 30735dfecf96Smrg if (mpi_cmp(rem, &test) <= 0) 30745dfecf96Smrg state = NDIVIDE_SUB; 30755dfecf96Smrg } 30765dfecf96Smrg } 30775dfecf96Smrg else { 30785dfecf96Smrg if (rsign > 0) { 30795dfecf96Smrg mpi_neg(&test, &test); 30805dfecf96Smrg mpi_addi(&test, &test, 1); 30815dfecf96Smrg mpi_divi(&test, &test, 2); 30825dfecf96Smrg if (mpi_cmp(rem, &test) >= 0) 30835dfecf96Smrg state = NDIVIDE_SUB; 30845dfecf96Smrg } 30855dfecf96Smrg else { 30865dfecf96Smrg mpi_subi(&test, &test, 1); 30875dfecf96Smrg mpi_divi(&test, &test, 2); 30885dfecf96Smrg if (mpi_cmp(rem, &test) <= 0) 30895dfecf96Smrg state = NDIVIDE_ADD; 30905dfecf96Smrg } 30915dfecf96Smrg } 30925dfecf96Smrg mpi_clear(&test); 30935dfecf96Smrg } break; 30945dfecf96Smrg } 30955dfecf96Smrg 30965dfecf96Smrg if (state == NDIVIDE_ADD) { 30975dfecf96Smrg mpi_addi(quo, quo, 1); 30985dfecf96Smrg switch (type) { 30995dfecf96Smrg case LispFixnum_t: 31005dfecf96Smrg mpi_subi(rem, rem, OFI(div)); 31015dfecf96Smrg break; 31025dfecf96Smrg case LispInteger_t: 31035dfecf96Smrg mpi_subi(rem, rem, OII(div)); 31045dfecf96Smrg break; 31055dfecf96Smrg default: 31065dfecf96Smrg mpi_sub(rem, rem, OBI(div)); 31075dfecf96Smrg } 31085dfecf96Smrg } 31095dfecf96Smrg else if (state == NDIVIDE_SUB) { 31105dfecf96Smrg mpi_subi(quo, quo, 1); 31115dfecf96Smrg switch (type) { 31125dfecf96Smrg case LispFixnum_t: 31135dfecf96Smrg mpi_addi(rem, rem, OFI(div)); 31145dfecf96Smrg break; 31155dfecf96Smrg case LispInteger_t: 31165dfecf96Smrg mpi_addi(rem, rem, OII(div)); 31175dfecf96Smrg break; 31185dfecf96Smrg default: 31195dfecf96Smrg mpi_add(rem, rem, OBI(div)); 31205dfecf96Smrg } 31215dfecf96Smrg } 31225dfecf96Smrg 31235dfecf96Smrg if (mpi_fiti(rem)) { 31245dfecf96Smrg NITYPE(num) = N_FIXNUM; 31255dfecf96Smrg NIFI(num) = mpi_geti(rem); 31265dfecf96Smrg mpi_clear(rem); 31275dfecf96Smrg XFREE(rem); 31285dfecf96Smrg } 31295dfecf96Smrg else { 31305dfecf96Smrg NITYPE(num) = N_BIGNUM; 31315dfecf96Smrg NIBI(num) = rem; 31325dfecf96Smrg } 31335dfecf96Smrg 31345dfecf96Smrg clear_real(NREAL(num)); 31355dfecf96Smrg 31365dfecf96Smrg if (flo) { 31375dfecf96Smrg double dval = bi_getd(quo); 31385dfecf96Smrg 31395dfecf96Smrg mpi_clear(quo); 31405dfecf96Smrg XFREE(quo); 31415dfecf96Smrg NRTYPE(num) = N_FLONUM; 31425dfecf96Smrg NRFF(num) = dval; 31435dfecf96Smrg } 31445dfecf96Smrg else { 31455dfecf96Smrg NRTYPE(num) = N_BIGNUM; 31465dfecf96Smrg NRBI(num) = quo; 31475dfecf96Smrg rbi_canonicalize(NREAL(num)); 31485dfecf96Smrg } 31495dfecf96Smrg} 31505dfecf96Smrg 31515dfecf96Smrgstatic void 31525dfecf96Smrgndivide_flonum(n_number *number, double num, double div, int fun, int flo) 31535dfecf96Smrg{ 31545dfecf96Smrg double quo, rem, modp, tmp; 31555dfecf96Smrg 31565dfecf96Smrg modp = modf(num / div, &quo); 31575dfecf96Smrg rem = num - quo * div; 31585dfecf96Smrg 31595dfecf96Smrg switch (fun) { 31605dfecf96Smrg case NDIVIDE_CEIL: 31615dfecf96Smrg if ((rem < 0.0 && div < 0.0) || (rem > 0.0 && div > 0.0)) { 31625dfecf96Smrg quo += 1.0; 31635dfecf96Smrg rem -= div; 31645dfecf96Smrg } 31655dfecf96Smrg break; 31665dfecf96Smrg case NDIVIDE_FLOOR: 31675dfecf96Smrg if ((rem < 0.0 && div > 0.0) || (rem > 0.0 && div < 0.0)) { 31685dfecf96Smrg quo -= 1.0; 31695dfecf96Smrg rem += div; 31705dfecf96Smrg } 31715dfecf96Smrg break; 31725dfecf96Smrg case NDIVIDE_ROUND: 31735dfecf96Smrg if (fabs(modp) != 0.5 || modf(quo * 0.5, &tmp) != 0.0) { 31745dfecf96Smrg if (div > 0.0) { 31755dfecf96Smrg if (rem > 0.0) { 31765dfecf96Smrg if (rem >= div * 0.5) { 31775dfecf96Smrg quo += 1.0; 31785dfecf96Smrg rem -= div; 31795dfecf96Smrg } 31805dfecf96Smrg } 31815dfecf96Smrg else { 31825dfecf96Smrg if (rem <= div * -0.5) { 31835dfecf96Smrg quo -= 1.0; 31845dfecf96Smrg rem += div; 31855dfecf96Smrg } 31865dfecf96Smrg } 31875dfecf96Smrg } 31885dfecf96Smrg else { 31895dfecf96Smrg if (rem > 0.0) { 31905dfecf96Smrg if (rem >= div * -0.5) { 31915dfecf96Smrg quo -= 1.0; 31925dfecf96Smrg rem += div; 31935dfecf96Smrg } 31945dfecf96Smrg } 31955dfecf96Smrg else { 31965dfecf96Smrg if (rem <= div * 0.5) { 31975dfecf96Smrg quo += 1.0; 31985dfecf96Smrg rem -= div; 31995dfecf96Smrg } 32005dfecf96Smrg } 32015dfecf96Smrg } 32025dfecf96Smrg } 32035dfecf96Smrg break; 32045dfecf96Smrg } 32055dfecf96Smrg if (!finite(quo) || !finite(rem)) 32065dfecf96Smrg fatal_error(FLOATING_POINT_OVERFLOW); 32075dfecf96Smrg 32085dfecf96Smrg NITYPE(number) = N_FLONUM; 32095dfecf96Smrg NIFF(number) = rem; 32105dfecf96Smrg 32115dfecf96Smrg clear_real(NREAL(number)); 32125dfecf96Smrg 32135dfecf96Smrg if (flo) { 32145dfecf96Smrg NRTYPE(number) = N_FLONUM; 32155dfecf96Smrg NRFF(number) = quo; 32165dfecf96Smrg } 32175dfecf96Smrg else { 32185dfecf96Smrg if ((long)quo == quo) { 32195dfecf96Smrg NRTYPE(number) = N_FIXNUM; 32205dfecf96Smrg NRFI(number) = (long)quo; 32215dfecf96Smrg } 32225dfecf96Smrg else { 32235dfecf96Smrg mpi *bigi = XALLOC(mpi); 32245dfecf96Smrg 32255dfecf96Smrg mpi_init(bigi); 32265dfecf96Smrg mpi_setd(bigi, quo); 32275dfecf96Smrg NRBI(number) = bigi; 32285dfecf96Smrg NRTYPE(number) = N_BIGNUM; 32295dfecf96Smrg } 32305dfecf96Smrg } 32315dfecf96Smrg} 32325dfecf96Smrg 32335dfecf96Smrgstatic void 32345dfecf96Smrgndivide_xi_xr(n_number *num, LispObj *div, int fun, int flo) 32355dfecf96Smrg{ 32365dfecf96Smrg int state = NDIVIDE_NOP, dsign, rsign; 32375dfecf96Smrg mpi *quo; 32385dfecf96Smrg mpr *rem; 32395dfecf96Smrg 32405dfecf96Smrg quo = XALLOC(mpi); 32415dfecf96Smrg mpi_init(quo); 32425dfecf96Smrg if (NRTYPE(num) == N_FIXNUM) 32435dfecf96Smrg mpi_seti(quo, NRFI(num)); 32445dfecf96Smrg else 32455dfecf96Smrg mpi_set(quo, NRBI(num)); 32465dfecf96Smrg 32475dfecf96Smrg rem = XALLOC(mpr); 32485dfecf96Smrg mpr_init(rem); 32495dfecf96Smrg 32505dfecf96Smrg if (XOBJECT_TYPE(div) == LispRatio_t) 32515dfecf96Smrg mpr_seti(rem, OFRN(div), OFRD(div)); 32525dfecf96Smrg else 32535dfecf96Smrg mpr_set(rem, OBR(div)); 32545dfecf96Smrg dsign = mpi_sgn(mpr_num(rem)); 32555dfecf96Smrg mpi_mul(quo, quo, mpr_den(rem)); 32565dfecf96Smrg 32575dfecf96Smrg mpi_divqr(quo, mpr_num(rem), quo, mpr_num(rem)); 32585dfecf96Smrg mpr_canonicalize(rem); 32595dfecf96Smrg 32605dfecf96Smrg rsign = mpi_sgn(mpr_num(rem)); 32615dfecf96Smrg if (mpr_fiti(rem)) { 32625dfecf96Smrg if (mpi_geti(mpr_den(rem)) == 1) { 32635dfecf96Smrg NITYPE(num) = N_FIXNUM; 32645dfecf96Smrg NIFI(num) = mpi_geti(mpr_num(rem)); 32655dfecf96Smrg } 32665dfecf96Smrg else { 32675dfecf96Smrg NITYPE(num) = N_FIXRATIO; 32685dfecf96Smrg NIFRN(num) = mpi_geti(mpr_num(rem)); 32695dfecf96Smrg NIFRD(num) = mpi_geti(mpr_den(rem)); 32705dfecf96Smrg } 32715dfecf96Smrg mpr_clear(rem); 32725dfecf96Smrg XFREE(rem); 32735dfecf96Smrg } 32745dfecf96Smrg else { 32755dfecf96Smrg if (mpi_fiti(mpr_den(rem)) && mpi_geti(mpr_den(rem)) == 1) { 32765dfecf96Smrg NITYPE(num) = N_BIGNUM; 32775dfecf96Smrg NIBI(num) = mpr_num(rem); 32785dfecf96Smrg mpi_clear(mpr_den(rem)); 32795dfecf96Smrg XFREE(rem); 32805dfecf96Smrg } 32815dfecf96Smrg else { 32825dfecf96Smrg NITYPE(num) = N_BIGRATIO; 32835dfecf96Smrg NIBR(num) = rem; 32845dfecf96Smrg } 32855dfecf96Smrg } 32865dfecf96Smrg 32875dfecf96Smrg switch (fun) { 32885dfecf96Smrg case NDIVIDE_CEIL: 32895dfecf96Smrg if ((rsign < 0 && dsign < 0) || (rsign > 0 && dsign > 0)) 32905dfecf96Smrg state = NDIVIDE_ADD; 32915dfecf96Smrg break; 32925dfecf96Smrg case NDIVIDE_FLOOR: 32935dfecf96Smrg if ((rsign < 0 && dsign > 0) || (rsign > 0 && dsign < 0)) 32945dfecf96Smrg state = NDIVIDE_SUB; 32955dfecf96Smrg break; 32965dfecf96Smrg case NDIVIDE_ROUND: { 32975dfecf96Smrg n_real cmp; 32985dfecf96Smrg 32995dfecf96Smrg set_real_object(&cmp, div); 33005dfecf96Smrg div_real_real(&cmp, &two); 33015dfecf96Smrg if (dsign > 0) { 33025dfecf96Smrg if (rsign > 0) { 33035dfecf96Smrg if (cmp_real_real(NIMAG(num), &cmp) >= 0) 33045dfecf96Smrg state = NDIVIDE_ADD; 33055dfecf96Smrg } 33065dfecf96Smrg else { 33075dfecf96Smrg neg_real(&cmp); 33085dfecf96Smrg if (cmp_real_real(NIMAG(num), &cmp) <= 0) 33095dfecf96Smrg state = NDIVIDE_SUB; 33105dfecf96Smrg } 33115dfecf96Smrg } 33125dfecf96Smrg else { 33135dfecf96Smrg if (rsign > 0) { 33145dfecf96Smrg neg_real(&cmp); 33155dfecf96Smrg if (cmp_real_real(NIMAG(num), &cmp) >= 0) 33165dfecf96Smrg state = NDIVIDE_SUB; 33175dfecf96Smrg } 33185dfecf96Smrg else { 33195dfecf96Smrg if (cmp_real_real(NIMAG(num), &cmp) <= 0) 33205dfecf96Smrg state = NDIVIDE_ADD; 33215dfecf96Smrg } 33225dfecf96Smrg } 33235dfecf96Smrg clear_real(&cmp); 33245dfecf96Smrg } break; 33255dfecf96Smrg } 33265dfecf96Smrg 33275dfecf96Smrg if (state == NDIVIDE_ADD) { 33285dfecf96Smrg mpi_addi(quo, quo, 1); 33295dfecf96Smrg sub_real_object(NIMAG(num), div); 33305dfecf96Smrg } 33315dfecf96Smrg else if (state == NDIVIDE_SUB) { 33325dfecf96Smrg mpi_subi(quo, quo, 1); 33335dfecf96Smrg add_real_object(NIMAG(num), div); 33345dfecf96Smrg } 33355dfecf96Smrg 33365dfecf96Smrg clear_real(NREAL(num)); 33375dfecf96Smrg 33385dfecf96Smrg if (flo) { 33395dfecf96Smrg double dval = bi_getd(quo); 33405dfecf96Smrg 33415dfecf96Smrg mpi_clear(quo); 33425dfecf96Smrg XFREE(quo); 33435dfecf96Smrg NRTYPE(num) = N_FLONUM; 33445dfecf96Smrg NRFF(num) = dval; 33455dfecf96Smrg } 33465dfecf96Smrg else { 33475dfecf96Smrg NRBI(num) = quo; 33485dfecf96Smrg NRTYPE(num) = N_BIGNUM; 33495dfecf96Smrg rbi_canonicalize(NREAL(num)); 33505dfecf96Smrg } 33515dfecf96Smrg} 33525dfecf96Smrg 33535dfecf96Smrgstatic void 33545dfecf96Smrgndivide_xr_xi(n_number *num, LispObj *div, int fun, int flo) 33555dfecf96Smrg{ 33565dfecf96Smrg LispType type = OBJECT_TYPE(div); 33575dfecf96Smrg int state = NDIVIDE_NOP, dsign, rsign; 33585dfecf96Smrg mpi *quo; 33595dfecf96Smrg mpr *rem; 33605dfecf96Smrg 33615dfecf96Smrg quo = XALLOC(mpi); 33625dfecf96Smrg mpi_init(quo); 33635dfecf96Smrg switch (type) { 33645dfecf96Smrg case LispFixnum_t: 33655dfecf96Smrg dsign = OFI(div) < 0 ? -1 : OFI(div) > 0 ? 1 : 0; 33665dfecf96Smrg mpi_seti(quo, OFI(div)); 33675dfecf96Smrg break; 33685dfecf96Smrg case LispInteger_t: 33695dfecf96Smrg dsign = OII(div) < 0 ? -1 : OII(div) > 0 ? 1 : 0; 33705dfecf96Smrg mpi_seti(quo, OII(div)); 33715dfecf96Smrg break; 33725dfecf96Smrg default: 33735dfecf96Smrg dsign = mpi_sgn(OBI(div)); 33745dfecf96Smrg mpi_set(quo, OBI(div)); 33755dfecf96Smrg break; 33765dfecf96Smrg } 33775dfecf96Smrg 33785dfecf96Smrg rem = XALLOC(mpr); 33795dfecf96Smrg mpr_init(rem); 33805dfecf96Smrg if (NRTYPE(num) == N_FIXRATIO) { 33815dfecf96Smrg mpr_seti(rem, NRFRN(num), NRFRD(num)); 33825dfecf96Smrg mpi_muli(quo, quo, NRFRD(num)); 33835dfecf96Smrg } 33845dfecf96Smrg else { 33855dfecf96Smrg mpr_set(rem, NRBR(num)); 33865dfecf96Smrg mpi_mul(quo, quo, NRBRD(num)); 33875dfecf96Smrg } 33885dfecf96Smrg mpi_divqr(quo, mpr_num(rem), mpr_num(rem), quo); 33895dfecf96Smrg mpr_canonicalize(rem); 33905dfecf96Smrg 33915dfecf96Smrg rsign = mpi_sgn(mpr_num(rem)); 33925dfecf96Smrg if (mpr_fiti(rem)) { 33935dfecf96Smrg NITYPE(num) = N_FIXRATIO; 33945dfecf96Smrg NIFRN(num) = mpi_geti(mpr_num(rem)); 33955dfecf96Smrg NIFRD(num) = mpi_geti(mpr_den(rem)); 33965dfecf96Smrg mpr_clear(rem); 33975dfecf96Smrg XFREE(rem); 33985dfecf96Smrg } 33995dfecf96Smrg else { 34005dfecf96Smrg NITYPE(num) = N_BIGRATIO; 34015dfecf96Smrg NIBR(num) = rem; 34025dfecf96Smrg } 34035dfecf96Smrg 34045dfecf96Smrg switch (fun) { 34055dfecf96Smrg case NDIVIDE_CEIL: 34065dfecf96Smrg if ((rsign < 0 && dsign < 0) || (rsign > 0 && dsign > 0)) 34075dfecf96Smrg state = NDIVIDE_ADD; 34085dfecf96Smrg break; 34095dfecf96Smrg case NDIVIDE_FLOOR: 34105dfecf96Smrg if ((rsign < 0 && dsign > 0) || (rsign > 0 && dsign < 0)) 34115dfecf96Smrg state = NDIVIDE_SUB; 34125dfecf96Smrg break; 34135dfecf96Smrg case NDIVIDE_ROUND: { 34145dfecf96Smrg n_real cmp; 34155dfecf96Smrg 34165dfecf96Smrg set_real_object(&cmp, div); 34175dfecf96Smrg div_real_real(&cmp, &two); 34185dfecf96Smrg if (dsign > 0) { 34195dfecf96Smrg if (rsign > 0) { 34205dfecf96Smrg if (cmp_real_real(NIMAG(num), &cmp) >= 0) 34215dfecf96Smrg state = NDIVIDE_ADD; 34225dfecf96Smrg } 34235dfecf96Smrg else { 34245dfecf96Smrg neg_real(&cmp); 34255dfecf96Smrg if (cmp_real_real(NIMAG(num), &cmp) <= 0) 34265dfecf96Smrg state = NDIVIDE_SUB; 34275dfecf96Smrg } 34285dfecf96Smrg } 34295dfecf96Smrg else { 34305dfecf96Smrg if (rsign > 0) { 34315dfecf96Smrg neg_real(&cmp); 34325dfecf96Smrg if (cmp_real_real(NIMAG(num), &cmp) >= 0) 34335dfecf96Smrg state = NDIVIDE_SUB; 34345dfecf96Smrg } 34355dfecf96Smrg else { 34365dfecf96Smrg if (cmp_real_real(NIMAG(num), &cmp) <= 0) 34375dfecf96Smrg state = NDIVIDE_ADD; 34385dfecf96Smrg } 34395dfecf96Smrg } 34405dfecf96Smrg clear_real(&cmp); 34415dfecf96Smrg } break; 34425dfecf96Smrg } 34435dfecf96Smrg 34445dfecf96Smrg if (state == NDIVIDE_ADD) { 34455dfecf96Smrg mpi_addi(quo, quo, 1); 34465dfecf96Smrg sub_real_object(NIMAG(num), div); 34475dfecf96Smrg } 34485dfecf96Smrg else if (state == NDIVIDE_SUB) { 34495dfecf96Smrg mpi_subi(quo, quo, 1); 34505dfecf96Smrg add_real_object(NIMAG(num), div); 34515dfecf96Smrg } 34525dfecf96Smrg 34535dfecf96Smrg clear_real(NREAL(num)); 34545dfecf96Smrg 34555dfecf96Smrg if (flo) { 34565dfecf96Smrg double dval = bi_getd(quo); 34575dfecf96Smrg 34585dfecf96Smrg mpi_clear(quo); 34595dfecf96Smrg XFREE(quo); 34605dfecf96Smrg NRTYPE(num) = N_FLONUM; 34615dfecf96Smrg NRFF(num) = dval; 34625dfecf96Smrg } 34635dfecf96Smrg else { 34645dfecf96Smrg NRBI(num) = quo; 34655dfecf96Smrg NRTYPE(num) = N_BIGNUM; 34665dfecf96Smrg rbi_canonicalize(NREAL(num)); 34675dfecf96Smrg } 34685dfecf96Smrg} 34695dfecf96Smrg 34705dfecf96Smrgstatic void 34715dfecf96Smrgndivide_xr_xr(n_number *num, LispObj *div, int fun, int flo) 34725dfecf96Smrg{ 34735dfecf96Smrg int state = NDIVIDE_NOP, dsign, rsign, modp; 34745dfecf96Smrg mpr *bigr; 34755dfecf96Smrg mpi *bigi; 34765dfecf96Smrg 34775dfecf96Smrg bigr = XALLOC(mpr); 34785dfecf96Smrg mpr_init(bigr); 34795dfecf96Smrg if (NRTYPE(num) == N_FIXRATIO) 34805dfecf96Smrg mpr_seti(bigr, NRFRN(num), NRFRD(num)); 34815dfecf96Smrg else 34825dfecf96Smrg mpr_set(bigr, NRBR(num)); 34835dfecf96Smrg 34845dfecf96Smrg NITYPE(num) = N_BIGRATIO; 34855dfecf96Smrg NIBR(num) = bigr; 34865dfecf96Smrg 34875dfecf96Smrg if (OBJECT_TYPE(div) == LispRatio_t) { 34885dfecf96Smrg dsign = OFRN(div) < 0 ? -1 : OFRN(div) > 0 ? 1 : 0; 34895dfecf96Smrg mpi_muli(mpr_num(bigr), mpr_num(bigr), OFRD(div)); 34905dfecf96Smrg mpi_muli(mpr_den(bigr), mpr_den(bigr), OFRN(div)); 34915dfecf96Smrg } 34925dfecf96Smrg else { 34935dfecf96Smrg dsign = mpi_sgn(OBRN(div)); 34945dfecf96Smrg mpr_div(bigr, bigr, OBR(div)); 34955dfecf96Smrg } 34965dfecf96Smrg modp = mpi_fiti(mpr_den(bigr)) && mpi_geti(mpr_den(bigr)) == 2; 34975dfecf96Smrg 34985dfecf96Smrg bigi = XALLOC(mpi); 34995dfecf96Smrg mpi_init(bigi); 35005dfecf96Smrg mpi_divqr(bigi, mpr_num(bigr), mpr_num(bigr), mpr_den(bigr)); 35015dfecf96Smrg 35025dfecf96Smrg if (OBJECT_TYPE(div) == LispRatio_t) 35035dfecf96Smrg mpi_seti(mpr_den(bigr), OFRD(div)); 35045dfecf96Smrg else 35055dfecf96Smrg mpi_set(mpr_den(bigr), OBRD(div)); 35065dfecf96Smrg if (NRTYPE(num) == N_FIXRATIO) 35075dfecf96Smrg mpi_muli(mpr_den(bigr), mpr_den(bigr), NRFRD(num)); 35085dfecf96Smrg else 35095dfecf96Smrg mpi_mul(mpr_den(bigr), mpr_den(bigr), NRBRD(num)); 35105dfecf96Smrg 35115dfecf96Smrg clear_real(NREAL(num)); 35125dfecf96Smrg NRTYPE(num) = N_BIGNUM; 35135dfecf96Smrg NRBI(num) = bigi; 35145dfecf96Smrg 35155dfecf96Smrg rbr_canonicalize(NIMAG(num)); 35165dfecf96Smrg rsign = cmp_real_real(NIMAG(num), &zero); 35175dfecf96Smrg 35185dfecf96Smrg switch (fun) { 35195dfecf96Smrg case NDIVIDE_CEIL: 35205dfecf96Smrg if ((rsign < 0 && dsign < 0) || (rsign > 0 && dsign > 0)) 35215dfecf96Smrg state = NDIVIDE_ADD; 35225dfecf96Smrg break; 35235dfecf96Smrg case NDIVIDE_FLOOR: 35245dfecf96Smrg if ((rsign < 0 && dsign > 0) || (rsign > 0 && dsign < 0)) 35255dfecf96Smrg state = NDIVIDE_SUB; 35265dfecf96Smrg break; 35275dfecf96Smrg case NDIVIDE_ROUND: 35285dfecf96Smrg if (!modp || (bigi->digs[0] & 1) == 1) { 35295dfecf96Smrg n_real cmp; 35305dfecf96Smrg 35315dfecf96Smrg set_real_object(&cmp, div); 35325dfecf96Smrg div_real_real(&cmp, &two); 35335dfecf96Smrg if (dsign > 0) { 35345dfecf96Smrg if (rsign > 0) { 35355dfecf96Smrg if (cmp_real_real(NIMAG(num), &cmp) >= 0) 35365dfecf96Smrg state = NDIVIDE_ADD; 35375dfecf96Smrg } 35385dfecf96Smrg else { 35395dfecf96Smrg neg_real(&cmp); 35405dfecf96Smrg if (cmp_real_real(NIMAG(num), &cmp) <= 0) 35415dfecf96Smrg state = NDIVIDE_SUB; 35425dfecf96Smrg } 35435dfecf96Smrg } 35445dfecf96Smrg else { 35455dfecf96Smrg if (rsign > 0) { 35465dfecf96Smrg neg_real(&cmp); 35475dfecf96Smrg if (cmp_real_real(NIMAG(num), &cmp) >= 0) 35485dfecf96Smrg state = NDIVIDE_SUB; 35495dfecf96Smrg } 35505dfecf96Smrg else { 35515dfecf96Smrg if (cmp_real_real(NIMAG(num), &cmp) <= 0) 35525dfecf96Smrg state = NDIVIDE_ADD; 35535dfecf96Smrg } 35545dfecf96Smrg } 35555dfecf96Smrg clear_real(&cmp); 35565dfecf96Smrg } 35575dfecf96Smrg break; 35585dfecf96Smrg } 35595dfecf96Smrg 35605dfecf96Smrg if (state == NDIVIDE_ADD) { 35615dfecf96Smrg add_real_real(NREAL(num), &one); 35625dfecf96Smrg sub_real_object(NIMAG(num), div); 35635dfecf96Smrg } 35645dfecf96Smrg else if (state == NDIVIDE_SUB) { 35655dfecf96Smrg sub_real_real(NREAL(num), &one); 35665dfecf96Smrg add_real_object(NIMAG(num), div); 35675dfecf96Smrg } 35685dfecf96Smrg 35695dfecf96Smrg if (NRTYPE(num) == N_BIGNUM) { 35705dfecf96Smrg if (flo) { 35715dfecf96Smrg double dval = bi_getd(bigi); 35725dfecf96Smrg 35735dfecf96Smrg mpi_clear(bigi); 35745dfecf96Smrg XFREE(bigi); 35755dfecf96Smrg NRTYPE(num) = N_FLONUM; 35765dfecf96Smrg NRFF(num) = dval; 35775dfecf96Smrg } 35785dfecf96Smrg else 35795dfecf96Smrg rbi_canonicalize(NREAL(num)); 35805dfecf96Smrg } 35815dfecf96Smrg else if (flo) { 35825dfecf96Smrg NRTYPE(num) = N_FLONUM; 35835dfecf96Smrg NRFF(num) = (double)NRFI(num); 35845dfecf96Smrg } 35855dfecf96Smrg} 35865dfecf96Smrg 35875dfecf96Smrg 35885dfecf96Smrg/************************************************************************ 35895dfecf96Smrg * REAL COMPLEX 35905dfecf96Smrg ************************************************************************/ 35915dfecf96Smrgstatic void 35925dfecf96Smrgnadd_re_cx(n_number *num, LispObj *comp) 35935dfecf96Smrg{ 35945dfecf96Smrg/* 35955dfecf96Smrg Ra+Rb Ib 35965dfecf96Smrg */ 35975dfecf96Smrg /* Ra+Rb */ 35985dfecf96Smrg add_real_object(NREAL(num), OCXR(comp)); 35995dfecf96Smrg 36005dfecf96Smrg /* Ib */ 36015dfecf96Smrg set_real_object(NIMAG(num), OCXI(comp)); 36025dfecf96Smrg 36035dfecf96Smrg num->complex = 1; 36045dfecf96Smrg 36055dfecf96Smrg ncx_canonicalize(num); 36065dfecf96Smrg} 36075dfecf96Smrg 36085dfecf96Smrgstatic void 36095dfecf96Smrgnsub_re_cx(n_number *num, LispObj *comp) 36105dfecf96Smrg{ 36115dfecf96Smrg/* 36125dfecf96Smrg Ra-Rb -Ib 36135dfecf96Smrg */ 36145dfecf96Smrg /* Ra-Rb */ 36155dfecf96Smrg sub_real_object(NREAL(num), OCXR(comp)); 36165dfecf96Smrg 36175dfecf96Smrg /* -Ib */ 36185dfecf96Smrg NITYPE(num) = N_FIXNUM; 36195dfecf96Smrg NIFI(num) = -1; 36205dfecf96Smrg mul_real_object(NIMAG(num), OCXI(comp)); 36215dfecf96Smrg 36225dfecf96Smrg num->complex = 1; 36235dfecf96Smrg 36245dfecf96Smrg ncx_canonicalize(num); 36255dfecf96Smrg} 36265dfecf96Smrg 36275dfecf96Smrgstatic void 36285dfecf96Smrgnmul_re_cx(n_number *num, LispObj *comp) 36295dfecf96Smrg{ 36305dfecf96Smrg/* 36315dfecf96Smrg Ra*Rb Ra*Ib 36325dfecf96Smrg */ 36335dfecf96Smrg /* copy before change */ 36345dfecf96Smrg set_real_real(NIMAG(num), NREAL(num)); 36355dfecf96Smrg 36365dfecf96Smrg /* Ra*Rb */ 36375dfecf96Smrg mul_real_object(NREAL(num), OCXR(comp)); 36385dfecf96Smrg 36395dfecf96Smrg /* Ra*Ib */ 36405dfecf96Smrg mul_real_object(NIMAG(num), OCXI(comp)); 36415dfecf96Smrg 36425dfecf96Smrg num->complex = 1; 36435dfecf96Smrg 36445dfecf96Smrg ncx_canonicalize(num); 36455dfecf96Smrg} 36465dfecf96Smrg 36475dfecf96Smrgstatic void 36485dfecf96Smrgndiv_re_cx(n_number *num, LispObj *comp) 36495dfecf96Smrg{ 36505dfecf96Smrg/* 36515dfecf96Smrg Ra*Rb -Ib*Ra 36525dfecf96Smrg ----------- ----------- 36535dfecf96Smrg Rb*Rb+Ib*Ib Rb*Rb+Ib*Ib 36545dfecf96Smrg */ 36555dfecf96Smrg n_real div, temp; 36565dfecf96Smrg 36575dfecf96Smrg /* Rb*Rb */ 36585dfecf96Smrg set_real_object(&div, OCXR(comp)); 36595dfecf96Smrg mul_real_object(&div, OCXR(comp)); 36605dfecf96Smrg 36615dfecf96Smrg /* Ib*Ib */ 36625dfecf96Smrg set_real_object(&temp, OCXI(comp)); 36635dfecf96Smrg mul_real_object(&temp, OCXI(comp)); 36645dfecf96Smrg 36655dfecf96Smrg /* Rb*Rb+Ib*Ib */ 36665dfecf96Smrg add_real_real(&div, &temp); 36675dfecf96Smrg clear_real(&temp); 36685dfecf96Smrg 36695dfecf96Smrg /* -Ib*Ra */ 36705dfecf96Smrg NITYPE(num) = N_FIXNUM; 36715dfecf96Smrg NIFI(num) = -1; 36725dfecf96Smrg mul_real_object(NIMAG(num), OCXI(comp)); 36735dfecf96Smrg mul_real_real(NIMAG(num), NREAL(num)); 36745dfecf96Smrg 36755dfecf96Smrg /* Ra*Rb */ 36765dfecf96Smrg mul_real_object(NREAL(num), OCXR(comp)); 36775dfecf96Smrg 36785dfecf96Smrg div_real_real(NREAL(num), &div); 36795dfecf96Smrg div_real_real(NIMAG(num), &div); 36805dfecf96Smrg clear_real(&div); 36815dfecf96Smrg 36825dfecf96Smrg num->complex = 1; 36835dfecf96Smrg 36845dfecf96Smrg ncx_canonicalize(num); 36855dfecf96Smrg} 36865dfecf96Smrg 36875dfecf96Smrg 36885dfecf96Smrg/************************************************************************ 36895dfecf96Smrg * COMPLEX REAL 36905dfecf96Smrg ************************************************************************/ 36915dfecf96Smrgstatic void 36925dfecf96Smrgnadd_cx_re(n_number *num, LispObj *re) 36935dfecf96Smrg{ 36945dfecf96Smrg/* 36955dfecf96Smrg Ra+Rb Ia 36965dfecf96Smrg */ 36975dfecf96Smrg add_real_object(NREAL(num), re); 36985dfecf96Smrg 36995dfecf96Smrg ncx_canonicalize(num); 37005dfecf96Smrg} 37015dfecf96Smrg 37025dfecf96Smrgstatic void 37035dfecf96Smrgnsub_cx_re(n_number *num, LispObj *re) 37045dfecf96Smrg{ 37055dfecf96Smrg/* 37065dfecf96Smrg Ra-Rb Ia 37075dfecf96Smrg */ 37085dfecf96Smrg sub_real_object(NREAL(num), re); 37095dfecf96Smrg 37105dfecf96Smrg ncx_canonicalize(num); 37115dfecf96Smrg} 37125dfecf96Smrg 37135dfecf96Smrgstatic void 37145dfecf96Smrgnmul_cx_re(n_number *num, LispObj *re) 37155dfecf96Smrg{ 37165dfecf96Smrg/* 37175dfecf96Smrg Ra*Rb Ia*Rb 37185dfecf96Smrg */ 37195dfecf96Smrg mul_real_object(NREAL(num), re); 37205dfecf96Smrg mul_real_object(NIMAG(num), re); 37215dfecf96Smrg 37225dfecf96Smrg ncx_canonicalize(num); 37235dfecf96Smrg} 37245dfecf96Smrg 37255dfecf96Smrgstatic void 37265dfecf96Smrgndiv_cx_re(n_number *num, LispObj *re) 37275dfecf96Smrg{ 37285dfecf96Smrg/* 37295dfecf96Smrg Ra/Rb Ia/Rb 37305dfecf96Smrg */ 37315dfecf96Smrg div_real_object(NREAL(num), re); 37325dfecf96Smrg div_real_object(NIMAG(num), re); 37335dfecf96Smrg 37345dfecf96Smrg ncx_canonicalize(num); 37355dfecf96Smrg} 37365dfecf96Smrg 37375dfecf96Smrg 37385dfecf96Smrg/************************************************************************ 37395dfecf96Smrg * COMPLEX COMPLEX 37405dfecf96Smrg ************************************************************************/ 37415dfecf96Smrgstatic void 37425dfecf96Smrgnadd_cx_cx(n_number *num, LispObj *comp) 37435dfecf96Smrg{ 37445dfecf96Smrg/* 37455dfecf96Smrg Ra+Rb Ia+Ib 37465dfecf96Smrg */ 37475dfecf96Smrg add_real_object(NREAL(num), OCXR(comp)); 37485dfecf96Smrg add_real_object(NIMAG(num), OCXI(comp)); 37495dfecf96Smrg 37505dfecf96Smrg ncx_canonicalize(num); 37515dfecf96Smrg} 37525dfecf96Smrg 37535dfecf96Smrgstatic void 37545dfecf96Smrgnsub_cx_cx(n_number *num, LispObj *comp) 37555dfecf96Smrg{ 37565dfecf96Smrg/* 37575dfecf96Smrg Ra-Rb Ia-Ib 37585dfecf96Smrg */ 37595dfecf96Smrg sub_real_object(NREAL(num), OCXR(comp)); 37605dfecf96Smrg sub_real_object(NIMAG(num), OCXI(comp)); 37615dfecf96Smrg 37625dfecf96Smrg ncx_canonicalize(num); 37635dfecf96Smrg} 37645dfecf96Smrg 37655dfecf96Smrgstatic void 37665dfecf96Smrgnmul_cx_cx(n_number *num, LispObj *comp) 37675dfecf96Smrg{ 37685dfecf96Smrg/* 37695dfecf96Smrg Ra*Rb-Ia*Ib Ra*Ib+Ia*Rb 37705dfecf96Smrg */ 37715dfecf96Smrg n_real IaIb, RaIb; 37725dfecf96Smrg 37735dfecf96Smrg set_real_real(&IaIb, NIMAG(num)); 37745dfecf96Smrg mul_real_object(&IaIb, OCXI(comp)); 37755dfecf96Smrg 37765dfecf96Smrg set_real_real(&RaIb, NREAL(num)); 37775dfecf96Smrg mul_real_object(&RaIb, OCXI(comp)); 37785dfecf96Smrg 37795dfecf96Smrg /* Ra*Rb-Ia*Ib */ 37805dfecf96Smrg mul_real_object(NREAL(num), OCXR(comp)); 37815dfecf96Smrg sub_real_real(NREAL(num), &IaIb); 37825dfecf96Smrg clear_real(&IaIb); 37835dfecf96Smrg 37845dfecf96Smrg /* Ra*Ib+Ia*Rb */ 37855dfecf96Smrg mul_real_object(NIMAG(num), OCXR(comp)); 37865dfecf96Smrg add_real_real(NIMAG(num), &RaIb); 37875dfecf96Smrg clear_real(&RaIb); 37885dfecf96Smrg 37895dfecf96Smrg ncx_canonicalize(num); 37905dfecf96Smrg} 37915dfecf96Smrg 37925dfecf96Smrgstatic void 37935dfecf96Smrgndiv_cx_cx(n_number *num, LispObj *comp) 37945dfecf96Smrg{ 37955dfecf96Smrg/* 37965dfecf96Smrg Ra*Rb+Ia*Ib Ia*Rb-Ib*Ra 37975dfecf96Smrg ----------- ----------- 37985dfecf96Smrg Rb*Rb+Ib*Ib Rb*Rb+Ib*Ib 37995dfecf96Smrg */ 38005dfecf96Smrg n_real temp1, temp2; 38015dfecf96Smrg 38025dfecf96Smrg /* IaIb */ 38035dfecf96Smrg set_real_real(&temp1, NIMAG(num)); 38045dfecf96Smrg mul_real_object(&temp1, OCXI(comp)); 38055dfecf96Smrg 38065dfecf96Smrg /* IbRa */ 38075dfecf96Smrg set_real_real(&temp2, NREAL(num)); 38085dfecf96Smrg mul_real_object(&temp2, OCXI(comp)); 38095dfecf96Smrg 38105dfecf96Smrg /* Ra*Rb+Ia*Ib */ 38115dfecf96Smrg mul_real_object(NREAL(num), OCXR(comp)); 38125dfecf96Smrg add_real_real(NREAL(num), &temp1); 38135dfecf96Smrg clear_real(&temp1); 38145dfecf96Smrg 38155dfecf96Smrg /* Ia*Rb-Ib*Ra */ 38165dfecf96Smrg mul_real_object(NIMAG(num), OCXR(comp)); 38175dfecf96Smrg sub_real_real(NIMAG(num), &temp2); 38185dfecf96Smrg clear_real(&temp2); 38195dfecf96Smrg 38205dfecf96Smrg 38215dfecf96Smrg /* Rb*Rb */ 38225dfecf96Smrg set_real_object(&temp1, OCXR(comp)); 38235dfecf96Smrg mul_real_object(&temp1, OCXR(comp)); 38245dfecf96Smrg 38255dfecf96Smrg /* Ib*Ib */ 38265dfecf96Smrg set_real_object(&temp2, OCXI(comp)); 38275dfecf96Smrg mul_real_object(&temp2, OCXI(comp)); 38285dfecf96Smrg 38295dfecf96Smrg /* Rb*Rb+Ib*Ib */ 38305dfecf96Smrg add_real_real(&temp1, &temp2); 38315dfecf96Smrg clear_real(&temp2); 38325dfecf96Smrg 38335dfecf96Smrg div_real_real(NREAL(num), &temp1); 38345dfecf96Smrg div_real_real(NIMAG(num), &temp1); 38355dfecf96Smrg clear_real(&temp1); 38365dfecf96Smrg 38375dfecf96Smrg ncx_canonicalize(num); 38385dfecf96Smrg} 38395dfecf96Smrg 38405dfecf96Smrgstatic int 38415dfecf96Smrgcmp_cx_cx(LispObj *op1, LispObj *op2) 38425dfecf96Smrg{ 38435dfecf96Smrg int cmp; 38445dfecf96Smrg 38455dfecf96Smrg cmp = cmp_object_object(OCXR(op1), OCXR(op2), 1); 38465dfecf96Smrg if (cmp == 0) 38475dfecf96Smrg cmp = cmp_object_object(OCXI(op1), OCXI(op2), 1); 38485dfecf96Smrg 38495dfecf96Smrg return (cmp); 38505dfecf96Smrg} 38515dfecf96Smrg 38525dfecf96Smrg 38535dfecf96Smrg/************************************************************************ 38545dfecf96Smrg * FLONUM FLONUM 38555dfecf96Smrg ************************************************************************/ 38565dfecf96Smrgstatic void 38575dfecf96Smrgradd_flonum(n_real *real, double op1, double op2) 38585dfecf96Smrg{ 38595dfecf96Smrg double value = op1 + op2; 38605dfecf96Smrg 38615dfecf96Smrg if (!finite(value)) 38625dfecf96Smrg fatal_error(FLOATING_POINT_OVERFLOW); 38635dfecf96Smrg switch (RTYPE(real)) { 38645dfecf96Smrg case N_FIXNUM: 38655dfecf96Smrg case N_FIXRATIO: 38665dfecf96Smrg RTYPE(real) = N_FLONUM; 38675dfecf96Smrg break; 38685dfecf96Smrg case N_BIGNUM: 38695dfecf96Smrg RCLEAR_BI(real); 38705dfecf96Smrg RTYPE(real) = N_FLONUM; 38715dfecf96Smrg break; 38725dfecf96Smrg case N_BIGRATIO: 38735dfecf96Smrg RCLEAR_BR(real); 38745dfecf96Smrg RTYPE(real) = N_FLONUM; 38755dfecf96Smrg break; 38765dfecf96Smrg } 38775dfecf96Smrg RFF(real) = value; 38785dfecf96Smrg} 38795dfecf96Smrg 38805dfecf96Smrgstatic void 38815dfecf96Smrgrsub_flonum(n_real *real, double op1, double op2) 38825dfecf96Smrg{ 38835dfecf96Smrg double value = op1 - op2; 38845dfecf96Smrg 38855dfecf96Smrg if (!finite(value)) 38865dfecf96Smrg fatal_error(FLOATING_POINT_OVERFLOW); 38875dfecf96Smrg switch (RTYPE(real)) { 38885dfecf96Smrg case N_FIXNUM: 38895dfecf96Smrg case N_FIXRATIO: 38905dfecf96Smrg RTYPE(real) = N_FLONUM; 38915dfecf96Smrg break; 38925dfecf96Smrg case N_BIGNUM: 38935dfecf96Smrg RCLEAR_BI(real); 38945dfecf96Smrg RTYPE(real) = N_FLONUM; 38955dfecf96Smrg break; 38965dfecf96Smrg case N_BIGRATIO: 38975dfecf96Smrg RCLEAR_BR(real); 38985dfecf96Smrg RTYPE(real) = N_FLONUM; 38995dfecf96Smrg break; 39005dfecf96Smrg } 39015dfecf96Smrg RFF(real) = value; 39025dfecf96Smrg} 39035dfecf96Smrg 39045dfecf96Smrgstatic void 39055dfecf96Smrgrmul_flonum(n_real *real, double op1, double op2) 39065dfecf96Smrg{ 39075dfecf96Smrg double value = op1 * op2; 39085dfecf96Smrg 39095dfecf96Smrg if (!finite(value)) 39105dfecf96Smrg fatal_error(FLOATING_POINT_OVERFLOW); 39115dfecf96Smrg switch (RTYPE(real)) { 39125dfecf96Smrg case N_FIXNUM: 39135dfecf96Smrg case N_FIXRATIO: 39145dfecf96Smrg RTYPE(real) = N_FLONUM; 39155dfecf96Smrg break; 39165dfecf96Smrg case N_BIGNUM: 39175dfecf96Smrg RCLEAR_BI(real); 39185dfecf96Smrg RTYPE(real) = N_FLONUM; 39195dfecf96Smrg break; 39205dfecf96Smrg case N_BIGRATIO: 39215dfecf96Smrg RCLEAR_BR(real); 39225dfecf96Smrg RTYPE(real) = N_FLONUM; 39235dfecf96Smrg break; 39245dfecf96Smrg } 39255dfecf96Smrg RFF(real) = value; 39265dfecf96Smrg} 39275dfecf96Smrg 39285dfecf96Smrgstatic void 39295dfecf96Smrgrdiv_flonum(n_real *real, double op1, double op2) 39305dfecf96Smrg{ 39315dfecf96Smrg double value; 39325dfecf96Smrg 39335dfecf96Smrg if (op2 == 0.0) 39345dfecf96Smrg fatal_error(DIVIDE_BY_ZERO); 39355dfecf96Smrg value = op1 / op2; 39365dfecf96Smrg if (!finite(value)) 39375dfecf96Smrg fatal_error(FLOATING_POINT_OVERFLOW); 39385dfecf96Smrg switch (RTYPE(real)) { 39395dfecf96Smrg case N_FIXNUM: 39405dfecf96Smrg case N_FIXRATIO: 39415dfecf96Smrg RTYPE(real) = N_FLONUM; 39425dfecf96Smrg break; 39435dfecf96Smrg case N_BIGNUM: 39445dfecf96Smrg RCLEAR_BI(real); 39455dfecf96Smrg RTYPE(real) = N_FLONUM; 39465dfecf96Smrg break; 39475dfecf96Smrg case N_BIGRATIO: 39485dfecf96Smrg RCLEAR_BR(real); 39495dfecf96Smrg RTYPE(real) = N_FLONUM; 39505dfecf96Smrg break; 39515dfecf96Smrg } 39525dfecf96Smrg RFF(real) = value; 39535dfecf96Smrg} 39545dfecf96Smrg 39555dfecf96Smrgstatic int 39565dfecf96Smrgcmp_flonum(double op1, double op2) 39575dfecf96Smrg{ 39585dfecf96Smrg double value = op1 - op2; 39595dfecf96Smrg 39605dfecf96Smrg if (!finite(value)) 39615dfecf96Smrg fatal_error(FLOATING_POINT_OVERFLOW); 39625dfecf96Smrg 39635dfecf96Smrg return (value > 0.0 ? 1 : value < 0.0 ? -1 : 0); 39645dfecf96Smrg} 39655dfecf96Smrg 39665dfecf96Smrg 39675dfecf96Smrg/************************************************************************ 39685dfecf96Smrg * FIXNUM FIXNUM 39695dfecf96Smrg ************************************************************************/ 39705dfecf96Smrgstatic void 39715dfecf96Smrgrop_fi_fi_bi(n_real *real, long fi, int op) 39725dfecf96Smrg{ 39735dfecf96Smrg mpi *bigi = XALLOC(mpi); 39745dfecf96Smrg 39755dfecf96Smrg mpi_init(bigi); 39765dfecf96Smrg mpi_seti(bigi, RFI(real)); 39775dfecf96Smrg if (op == NOP_ADD) 39785dfecf96Smrg mpi_addi(bigi, bigi, fi); 39795dfecf96Smrg else if (op == NOP_SUB) 39805dfecf96Smrg mpi_subi(bigi, bigi, fi); 39815dfecf96Smrg else 39825dfecf96Smrg mpi_muli(bigi, bigi, fi); 39835dfecf96Smrg RBI(real) = bigi; 39845dfecf96Smrg RTYPE(real) = N_BIGNUM; 39855dfecf96Smrg} 39865dfecf96Smrg 39875dfecf96Smrgstatic INLINE void 39885dfecf96Smrgradd_fi_fi(n_real *real, long fi) 39895dfecf96Smrg{ 39905dfecf96Smrg if (!fi_fi_add_overflow(RFI(real), fi)) 39915dfecf96Smrg RFI(real) += fi; 39925dfecf96Smrg else 39935dfecf96Smrg rop_fi_fi_bi(real, fi, NOP_ADD); 39945dfecf96Smrg} 39955dfecf96Smrg 39965dfecf96Smrgstatic INLINE void 39975dfecf96Smrgrsub_fi_fi(n_real *real, long fi) 39985dfecf96Smrg{ 39995dfecf96Smrg if (!fi_fi_sub_overflow(RFI(real), fi)) 40005dfecf96Smrg RFI(real) -= fi; 40015dfecf96Smrg else 40025dfecf96Smrg rop_fi_fi_bi(real, fi, NOP_SUB); 40035dfecf96Smrg} 40045dfecf96Smrg 40055dfecf96Smrgstatic INLINE void 40065dfecf96Smrgrmul_fi_fi(n_real *real, long fi) 40075dfecf96Smrg{ 40085dfecf96Smrg if (!fi_fi_mul_overflow(RFI(real), fi)) 40095dfecf96Smrg RFI(real) *= fi; 40105dfecf96Smrg else 40115dfecf96Smrg rop_fi_fi_bi(real, fi, NOP_MUL); 40125dfecf96Smrg} 40135dfecf96Smrg 40145dfecf96Smrgstatic INLINE void 40155dfecf96Smrgrdiv_fi_fi(n_real *real, long fi) 40165dfecf96Smrg{ 40175dfecf96Smrg RTYPE(real) = N_FIXRATIO; 40185dfecf96Smrg RFRN(real) = RFI(real); 40195dfecf96Smrg RFRD(real) = fi; 40205dfecf96Smrg rfr_canonicalize(real); 40215dfecf96Smrg} 40225dfecf96Smrg 40235dfecf96Smrgstatic INLINE int 40245dfecf96Smrgcmp_fi_fi(long op1, long op2) 40255dfecf96Smrg{ 40265dfecf96Smrg if (op1 > op2) 40275dfecf96Smrg return (1); 40285dfecf96Smrg else if (op1 < op2) 40295dfecf96Smrg return (-1); 40305dfecf96Smrg 40315dfecf96Smrg return (0); 40325dfecf96Smrg} 40335dfecf96Smrg 40345dfecf96Smrg 40355dfecf96Smrg/************************************************************************ 40365dfecf96Smrg * FIXNUM BIGNUM 40375dfecf96Smrg ************************************************************************/ 40385dfecf96Smrgstatic void 40395dfecf96Smrgrop_fi_bi_xi(n_real *real, mpi *bi, int nop) 40405dfecf96Smrg{ 40415dfecf96Smrg mpi *bigi = XALLOC(mpi); 40425dfecf96Smrg 40435dfecf96Smrg mpi_init(bigi); 40445dfecf96Smrg mpi_seti(bigi, RFI(real)); 40455dfecf96Smrg if (nop == NOP_ADD) 40465dfecf96Smrg mpi_add(bigi, bigi, bi); 40475dfecf96Smrg else if (nop == NOP_SUB) 40485dfecf96Smrg mpi_sub(bigi, bigi, bi); 40495dfecf96Smrg else 40505dfecf96Smrg mpi_mul(bigi, bigi, bi); 40515dfecf96Smrg 40525dfecf96Smrg if (mpi_fiti(bigi)) { 40535dfecf96Smrg RFI(real) = mpi_geti(bigi); 40545dfecf96Smrg mpi_clear(bigi); 40555dfecf96Smrg XFREE(bigi); 40565dfecf96Smrg } 40575dfecf96Smrg else { 40585dfecf96Smrg RBI(real) = bigi; 40595dfecf96Smrg RTYPE(real) = N_BIGNUM; 40605dfecf96Smrg } 40615dfecf96Smrg} 40625dfecf96Smrg 40635dfecf96Smrgstatic INLINE void 40645dfecf96Smrgradd_fi_bi(n_real *real, mpi *bi) 40655dfecf96Smrg{ 40665dfecf96Smrg rop_fi_bi_xi(real, bi, NOP_ADD); 40675dfecf96Smrg} 40685dfecf96Smrg 40695dfecf96Smrgstatic INLINE void 40705dfecf96Smrgrsub_fi_bi(n_real *real, mpi *bi) 40715dfecf96Smrg{ 40725dfecf96Smrg rop_fi_bi_xi(real, bi, NOP_SUB); 40735dfecf96Smrg} 40745dfecf96Smrg 40755dfecf96Smrgstatic INLINE void 40765dfecf96Smrgrmul_fi_bi(n_real *real, mpi *bi) 40775dfecf96Smrg{ 40785dfecf96Smrg rop_fi_bi_xi(real, bi, NOP_MUL); 40795dfecf96Smrg} 40805dfecf96Smrg 40815dfecf96Smrgstatic void 40825dfecf96Smrgrdiv_fi_bi(n_real *real, mpi *bi) 40835dfecf96Smrg{ 40845dfecf96Smrg mpr *bigr; 40855dfecf96Smrg 40865dfecf96Smrg if (mpi_cmpi(bi, 0) == 0) 40875dfecf96Smrg fatal_error(DIVIDE_BY_ZERO); 40885dfecf96Smrg 40895dfecf96Smrg bigr = XALLOC(mpr); 40905dfecf96Smrg mpr_init(bigr); 40915dfecf96Smrg mpi_seti(mpr_num(bigr), RFI(real)); 40925dfecf96Smrg mpi_set(mpr_den(bigr), bi); 40935dfecf96Smrg RBR(real) = bigr; 40945dfecf96Smrg RTYPE(real) = N_BIGRATIO; 40955dfecf96Smrg rbr_canonicalize(real); 40965dfecf96Smrg} 40975dfecf96Smrg 40985dfecf96Smrgstatic INLINE int 40995dfecf96Smrgcmp_fi_bi(long fixnum, mpi *bignum) 41005dfecf96Smrg{ 41015dfecf96Smrg return (-mpi_cmpi(bignum, fixnum)); 41025dfecf96Smrg} 41035dfecf96Smrg 41045dfecf96Smrg 41055dfecf96Smrg/************************************************************************ 41065dfecf96Smrg * FIXNUM FIXRATIO 41075dfecf96Smrg ************************************************************************/ 41085dfecf96Smrgstatic void 41095dfecf96Smrgrop_fi_fr_as_xr(n_real *real, long num, long den, int nop) 41105dfecf96Smrg{ 41115dfecf96Smrg int fit; 41125dfecf96Smrg long value = 0, op = RFI(real); 41135dfecf96Smrg 41145dfecf96Smrg fit = !fi_fi_mul_overflow(op, den); 41155dfecf96Smrg if (fit) { 41165dfecf96Smrg value = op * den; 41175dfecf96Smrg if (nop == NOP_ADD) 41185dfecf96Smrg fit = !fi_fi_add_overflow(value, num); 41195dfecf96Smrg else 41205dfecf96Smrg fit = !fi_fi_sub_overflow(value, num); 41215dfecf96Smrg } 41225dfecf96Smrg if (fit) { 41235dfecf96Smrg if (nop == NOP_ADD) 41245dfecf96Smrg RFRN(real) = value + num; 41255dfecf96Smrg else 41265dfecf96Smrg RFRN(real) = value - num; 41275dfecf96Smrg RFRD(real) = den; 41285dfecf96Smrg RTYPE(real) = N_FIXRATIO; 41295dfecf96Smrg rfr_canonicalize(real); 41305dfecf96Smrg } 41315dfecf96Smrg else { 41325dfecf96Smrg mpi iop; 41335dfecf96Smrg mpr *bigr = XALLOC(mpr); 41345dfecf96Smrg 41355dfecf96Smrg mpi_init(&iop); 41365dfecf96Smrg mpi_seti(&iop, op); 41375dfecf96Smrg mpi_muli(&iop, &iop, den); 41385dfecf96Smrg 41395dfecf96Smrg mpr_init(bigr); 41405dfecf96Smrg mpr_seti(bigr, num, den); 41415dfecf96Smrg if (nop == NOP_ADD) 41425dfecf96Smrg mpi_add(mpr_num(bigr), &iop, mpr_num(bigr)); 41435dfecf96Smrg else 41445dfecf96Smrg mpi_sub(mpr_num(bigr), &iop, mpr_num(bigr)); 41455dfecf96Smrg mpi_clear(&iop); 41465dfecf96Smrg RBR(real) = bigr; 41475dfecf96Smrg RTYPE(real) = N_BIGRATIO; 41485dfecf96Smrg rbr_canonicalize(real); 41495dfecf96Smrg } 41505dfecf96Smrg} 41515dfecf96Smrg 41525dfecf96Smrgstatic void 41535dfecf96Smrgrop_fi_fr_md_xr(n_real *real, long num, long den, int nop) 41545dfecf96Smrg{ 41555dfecf96Smrg int fit; 41565dfecf96Smrg long op = RFI(real); 41575dfecf96Smrg 41585dfecf96Smrg if (nop == NOP_MUL) 41595dfecf96Smrg fit = !fi_fi_mul_overflow(op, num); 41605dfecf96Smrg else 41615dfecf96Smrg fit = !fi_fi_mul_overflow(op, den); 41625dfecf96Smrg if (fit) { 41635dfecf96Smrg if (nop == NOP_MUL) { 41645dfecf96Smrg RFRN(real) = op * num; 41655dfecf96Smrg RFRD(real) = den; 41665dfecf96Smrg } 41675dfecf96Smrg else { 41685dfecf96Smrg RFRN(real) = op * den; 41695dfecf96Smrg RFRD(real) = num; 41705dfecf96Smrg } 41715dfecf96Smrg RTYPE(real) = N_FIXRATIO; 41725dfecf96Smrg rfr_canonicalize(real); 41735dfecf96Smrg } 41745dfecf96Smrg else { 41755dfecf96Smrg mpi iop; 41765dfecf96Smrg mpr *bigr = XALLOC(mpr); 41775dfecf96Smrg 41785dfecf96Smrg mpi_init(&iop); 41795dfecf96Smrg mpi_seti(&iop, op); 41805dfecf96Smrg 41815dfecf96Smrg mpr_init(bigr); 41825dfecf96Smrg if (nop == NOP_MUL) 41835dfecf96Smrg mpr_seti(bigr, num, den); 41845dfecf96Smrg else 41855dfecf96Smrg mpr_seti(bigr, den, num); 41865dfecf96Smrg mpi_mul(mpr_num(bigr), mpr_num(bigr), &iop); 41875dfecf96Smrg mpi_clear(&iop); 41885dfecf96Smrg RBR(real) = bigr; 41895dfecf96Smrg RTYPE(real) = N_BIGRATIO; 41905dfecf96Smrg rbr_canonicalize(real); 41915dfecf96Smrg } 41925dfecf96Smrg} 41935dfecf96Smrg 41945dfecf96Smrgstatic INLINE void 41955dfecf96Smrgradd_fi_fr(n_real *real, long num, long den) 41965dfecf96Smrg{ 41975dfecf96Smrg rop_fi_fr_as_xr(real, num, den, NOP_ADD); 41985dfecf96Smrg} 41995dfecf96Smrg 42005dfecf96Smrgstatic INLINE void 42015dfecf96Smrgrsub_fi_fr(n_real *real, long num, long den) 42025dfecf96Smrg{ 42035dfecf96Smrg rop_fi_fr_as_xr(real, num, den, NOP_SUB); 42045dfecf96Smrg} 42055dfecf96Smrg 42065dfecf96Smrgstatic INLINE void 42075dfecf96Smrgrmul_fi_fr(n_real *real, long num, long den) 42085dfecf96Smrg{ 42095dfecf96Smrg rop_fi_fr_md_xr(real, num, den, NOP_MUL); 42105dfecf96Smrg} 42115dfecf96Smrg 42125dfecf96Smrgstatic INLINE void 42135dfecf96Smrgrdiv_fi_fr(n_real *real, long num, long den) 42145dfecf96Smrg{ 42155dfecf96Smrg rop_fi_fr_md_xr(real, num, den, NOP_DIV); 42165dfecf96Smrg} 42175dfecf96Smrg 42185dfecf96Smrgstatic INLINE int 42195dfecf96Smrgcmp_fi_fr(long fi, long num, long den) 42205dfecf96Smrg{ 42215dfecf96Smrg return (cmp_flonum((double)fi, (double)num / (double)den)); 42225dfecf96Smrg} 42235dfecf96Smrg 42245dfecf96Smrg 42255dfecf96Smrg/************************************************************************ 42265dfecf96Smrg * FIXNUM BIGRATIO 42275dfecf96Smrg ************************************************************************/ 42285dfecf96Smrgstatic void 42295dfecf96Smrgrop_fi_br_as_xr(n_real *real, mpr *ratio, int nop) 42305dfecf96Smrg{ 42315dfecf96Smrg mpi iop; 42325dfecf96Smrg mpr *bigr = XALLOC(mpr); 42335dfecf96Smrg 42345dfecf96Smrg mpi_init(&iop); 42355dfecf96Smrg mpi_seti(&iop, RFI(real)); 42365dfecf96Smrg 42375dfecf96Smrg mpr_init(bigr); 42385dfecf96Smrg mpr_set(bigr, ratio); 42395dfecf96Smrg 42405dfecf96Smrg mpi_mul(&iop, &iop, mpr_den(ratio)); 42415dfecf96Smrg if (nop == NOP_ADD) 42425dfecf96Smrg mpi_add(mpr_num(bigr), &iop, mpr_num(bigr)); 42435dfecf96Smrg else 42445dfecf96Smrg mpi_sub(mpr_num(bigr), &iop, mpr_num(bigr)); 42455dfecf96Smrg 42465dfecf96Smrg mpi_clear(&iop); 42475dfecf96Smrg RBR(real) = bigr; 42485dfecf96Smrg RTYPE(real) = N_BIGRATIO; 42495dfecf96Smrg rbr_canonicalize(real); 42505dfecf96Smrg} 42515dfecf96Smrg 42525dfecf96Smrgstatic void 42535dfecf96Smrgrop_fi_br_md_xr(n_real *real, mpr *ratio, int nop) 42545dfecf96Smrg{ 42555dfecf96Smrg mpi iop; 42565dfecf96Smrg mpr *bigr = XALLOC(mpr); 42575dfecf96Smrg 42585dfecf96Smrg mpi_init(&iop); 42595dfecf96Smrg mpi_seti(&iop, RFI(real)); 42605dfecf96Smrg 42615dfecf96Smrg mpr_init(bigr); 42625dfecf96Smrg if (nop == NOP_MUL) 42635dfecf96Smrg mpr_set(bigr, ratio); 42645dfecf96Smrg else 42655dfecf96Smrg mpr_inv(bigr, ratio); 42665dfecf96Smrg 42675dfecf96Smrg mpi_mul(mpr_num(bigr), &iop, mpr_num(bigr)); 42685dfecf96Smrg 42695dfecf96Smrg mpi_clear(&iop); 42705dfecf96Smrg RBR(real) = bigr; 42715dfecf96Smrg RTYPE(real) = N_BIGRATIO; 42725dfecf96Smrg rbr_canonicalize(real); 42735dfecf96Smrg} 42745dfecf96Smrg 42755dfecf96Smrgstatic INLINE void 42765dfecf96Smrgradd_fi_br(n_real *real, mpr *ratio) 42775dfecf96Smrg{ 42785dfecf96Smrg rop_fi_br_as_xr(real, ratio, NOP_ADD); 42795dfecf96Smrg} 42805dfecf96Smrg 42815dfecf96Smrgstatic INLINE void 42825dfecf96Smrgrsub_fi_br(n_real *real, mpr *ratio) 42835dfecf96Smrg{ 42845dfecf96Smrg rop_fi_br_as_xr(real, ratio, NOP_SUB); 42855dfecf96Smrg} 42865dfecf96Smrg 42875dfecf96Smrgstatic INLINE void 42885dfecf96Smrgrmul_fi_br(n_real *real, mpr *ratio) 42895dfecf96Smrg{ 42905dfecf96Smrg rop_fi_br_md_xr(real, ratio, NOP_MUL); 42915dfecf96Smrg} 42925dfecf96Smrg 42935dfecf96Smrgstatic INLINE void 42945dfecf96Smrgrdiv_fi_br(n_real *real, mpr *ratio) 42955dfecf96Smrg{ 42965dfecf96Smrg rop_fi_br_md_xr(real, ratio, NOP_DIV); 42975dfecf96Smrg} 42985dfecf96Smrg 42995dfecf96Smrgstatic INLINE int 43005dfecf96Smrgcmp_fi_br(long op1, mpr *op2) 43015dfecf96Smrg{ 43025dfecf96Smrg return (-mpr_cmpi(op2, op1)); 43035dfecf96Smrg} 43045dfecf96Smrg 43055dfecf96Smrg 43065dfecf96Smrg/************************************************************************ 43075dfecf96Smrg * BIGNUM FIXNUM 43085dfecf96Smrg ************************************************************************/ 43095dfecf96Smrgstatic INLINE void 43105dfecf96Smrgradd_bi_fi(n_real *real, long fi) 43115dfecf96Smrg{ 43125dfecf96Smrg mpi_addi(RBI(real), RBI(real), fi); 43135dfecf96Smrg rbi_canonicalize(real); 43145dfecf96Smrg} 43155dfecf96Smrg 43165dfecf96Smrgstatic INLINE void 43175dfecf96Smrgrsub_bi_fi(n_real *real, long fi) 43185dfecf96Smrg{ 43195dfecf96Smrg mpi_subi(RBI(real), RBI(real), fi); 43205dfecf96Smrg rbi_canonicalize(real); 43215dfecf96Smrg} 43225dfecf96Smrg 43235dfecf96Smrgstatic INLINE void 43245dfecf96Smrgrmul_bi_fi(n_real *real, long fi) 43255dfecf96Smrg{ 43265dfecf96Smrg mpi_muli(RBI(real), RBI(real), fi); 43275dfecf96Smrg rbi_canonicalize(real); 43285dfecf96Smrg} 43295dfecf96Smrg 43305dfecf96Smrgstatic void 43315dfecf96Smrgrdiv_bi_fi(n_real *real, long fi) 43325dfecf96Smrg{ 43335dfecf96Smrg mpr *bigr; 43345dfecf96Smrg 43355dfecf96Smrg if (RFI(real) == 0) 43365dfecf96Smrg fatal_error(DIVIDE_BY_ZERO); 43375dfecf96Smrg 43385dfecf96Smrg bigr = XALLOC(mpr); 43395dfecf96Smrg mpr_init(bigr); 43405dfecf96Smrg mpi_set(mpr_num(bigr), RBI(real)); 43415dfecf96Smrg mpi_seti(mpr_den(bigr), fi); 43425dfecf96Smrg RCLEAR_BI(real); 43435dfecf96Smrg RBR(real) = bigr; 43445dfecf96Smrg RTYPE(real) = N_BIGRATIO; 43455dfecf96Smrg rbr_canonicalize(real); 43465dfecf96Smrg} 43475dfecf96Smrg 43485dfecf96Smrgstatic INLINE int 43495dfecf96Smrgcmp_bi_fi(mpi *bignum, long fi) 43505dfecf96Smrg{ 43515dfecf96Smrg return (mpi_cmpi(bignum, fi)); 43525dfecf96Smrg} 43535dfecf96Smrg 43545dfecf96Smrg 43555dfecf96Smrg/************************************************************************ 43565dfecf96Smrg * BIGNUM BIGNUM 43575dfecf96Smrg ************************************************************************/ 43585dfecf96Smrgstatic INLINE void 43595dfecf96Smrgradd_bi_bi(n_real *real, mpi *bignum) 43605dfecf96Smrg{ 43615dfecf96Smrg mpi_add(RBI(real), RBI(real), bignum); 43625dfecf96Smrg rbi_canonicalize(real); 43635dfecf96Smrg} 43645dfecf96Smrg 43655dfecf96Smrgstatic INLINE void 43665dfecf96Smrgrsub_bi_bi(n_real *real, mpi *bignum) 43675dfecf96Smrg{ 43685dfecf96Smrg mpi_sub(RBI(real), RBI(real), bignum); 43695dfecf96Smrg rbi_canonicalize(real); 43705dfecf96Smrg} 43715dfecf96Smrg 43725dfecf96Smrgstatic INLINE void 43735dfecf96Smrgrmul_bi_bi(n_real *real, mpi *bignum) 43745dfecf96Smrg{ 43755dfecf96Smrg mpi_mul(RBI(real), RBI(real), bignum); 43765dfecf96Smrg rbi_canonicalize(real); 43775dfecf96Smrg} 43785dfecf96Smrg 43795dfecf96Smrgstatic void 43805dfecf96Smrgrdiv_bi_bi(n_real *real, mpi *bignum) 43815dfecf96Smrg{ 43825dfecf96Smrg mpr *bigr; 43835dfecf96Smrg 43845dfecf96Smrg if (mpi_cmpi(bignum, 0) == 0) 43855dfecf96Smrg fatal_error(DIVIDE_BY_ZERO); 43865dfecf96Smrg 43875dfecf96Smrg bigr = XALLOC(mpr); 43885dfecf96Smrg mpr_init(bigr); 43895dfecf96Smrg mpi_set(mpr_num(bigr), RBI(real)); 43905dfecf96Smrg mpi_set(mpr_den(bigr), bignum); 43915dfecf96Smrg RCLEAR_BI(real); 43925dfecf96Smrg RBR(real) = bigr; 43935dfecf96Smrg RTYPE(real) = N_BIGRATIO; 43945dfecf96Smrg rbr_canonicalize(real); 43955dfecf96Smrg} 43965dfecf96Smrg 43975dfecf96Smrgstatic INLINE int 43985dfecf96Smrgcmp_bi_bi(mpi *op1, mpi *op2) 43995dfecf96Smrg{ 44005dfecf96Smrg return (mpi_cmp(op1, op2)); 44015dfecf96Smrg} 44025dfecf96Smrg 44035dfecf96Smrg 44045dfecf96Smrg/************************************************************************ 44055dfecf96Smrg * BIGNUM FIXRATIO 44065dfecf96Smrg ************************************************************************/ 44075dfecf96Smrgstatic void 44085dfecf96Smrgrop_bi_fr_as_xr(n_real *real, long num, long den, int nop) 44095dfecf96Smrg{ 44105dfecf96Smrg mpi iop; 44115dfecf96Smrg mpr *bigr = XALLOC(mpr); 44125dfecf96Smrg 44135dfecf96Smrg mpi_init(&iop); 44145dfecf96Smrg mpi_set(&iop, RBI(real)); 44155dfecf96Smrg mpi_muli(&iop, &iop, den); 44165dfecf96Smrg 44175dfecf96Smrg mpr_init(bigr); 44185dfecf96Smrg mpr_seti(bigr, num, den); 44195dfecf96Smrg 44205dfecf96Smrg if (nop == NOP_ADD) 44215dfecf96Smrg mpi_add(mpr_num(bigr), &iop, mpr_num(bigr)); 44225dfecf96Smrg else 44235dfecf96Smrg mpi_sub(mpr_num(bigr), &iop, mpr_num(bigr)); 44245dfecf96Smrg mpi_clear(&iop); 44255dfecf96Smrg 44265dfecf96Smrg RCLEAR_BI(real); 44275dfecf96Smrg RBR(real) = bigr; 44285dfecf96Smrg RTYPE(real) = N_BIGRATIO; 44295dfecf96Smrg rbr_canonicalize(real); 44305dfecf96Smrg} 44315dfecf96Smrg 44325dfecf96Smrgstatic INLINE void 44335dfecf96Smrgrop_bi_fr_md_xr(n_real *real, long num, long den, int nop) 44345dfecf96Smrg{ 44355dfecf96Smrg mpr *bigr = XALLOC(mpr); 44365dfecf96Smrg 44375dfecf96Smrg mpr_init(bigr); 44385dfecf96Smrg 44395dfecf96Smrg mpr_seti(bigr, num, den); 44405dfecf96Smrg 44415dfecf96Smrg if (nop == NOP_MUL) 44425dfecf96Smrg mpi_mul(mpr_num(bigr), RBI(real), mpr_num(bigr)); 44435dfecf96Smrg else { 44445dfecf96Smrg mpi_mul(mpr_den(bigr), RBI(real), mpr_den(bigr)); 44455dfecf96Smrg mpr_inv(bigr, bigr); 44465dfecf96Smrg } 44475dfecf96Smrg 44485dfecf96Smrg RCLEAR_BI(real); 44495dfecf96Smrg RBR(real) = bigr; 44505dfecf96Smrg RTYPE(real) = N_BIGRATIO; 44515dfecf96Smrg rbr_canonicalize(real); 44525dfecf96Smrg} 44535dfecf96Smrg 44545dfecf96Smrgstatic INLINE void 44555dfecf96Smrgradd_bi_fr(n_real *real, long num, long den) 44565dfecf96Smrg{ 44575dfecf96Smrg rop_bi_fr_as_xr(real, num, den, NOP_ADD); 44585dfecf96Smrg} 44595dfecf96Smrg 44605dfecf96Smrgstatic INLINE void 44615dfecf96Smrgrsub_bi_fr(n_real *real, long num, long den) 44625dfecf96Smrg{ 44635dfecf96Smrg rop_bi_fr_as_xr(real, num, den, NOP_SUB); 44645dfecf96Smrg} 44655dfecf96Smrg 44665dfecf96Smrgstatic INLINE void 44675dfecf96Smrgrmul_bi_fr(n_real *real, long num, long den) 44685dfecf96Smrg{ 44695dfecf96Smrg rop_bi_fr_md_xr(real, num, den, NOP_MUL); 44705dfecf96Smrg} 44715dfecf96Smrg 44725dfecf96Smrgstatic INLINE void 44735dfecf96Smrgrdiv_bi_fr(n_real *real, long num, long den) 44745dfecf96Smrg{ 44755dfecf96Smrg rop_bi_fr_md_xr(real, num, den, NOP_DIV); 44765dfecf96Smrg} 44775dfecf96Smrg 44785dfecf96Smrgstatic int 44795dfecf96Smrgcmp_bi_fr(mpi *bignum, long num, long den) 44805dfecf96Smrg{ 44815dfecf96Smrg int cmp; 44825dfecf96Smrg mpr cmp1, cmp2; 44835dfecf96Smrg 44845dfecf96Smrg mpr_init(&cmp1); 44855dfecf96Smrg mpi_set(mpr_num(&cmp1), bignum); 44865dfecf96Smrg mpi_seti(mpr_den(&cmp1), 1); 44875dfecf96Smrg 44885dfecf96Smrg mpr_init(&cmp2); 44895dfecf96Smrg mpr_seti(&cmp2, num, den); 44905dfecf96Smrg 44915dfecf96Smrg cmp = mpr_cmp(&cmp1, &cmp2); 44925dfecf96Smrg mpr_clear(&cmp1); 44935dfecf96Smrg mpr_clear(&cmp2); 44945dfecf96Smrg 44955dfecf96Smrg return (cmp); 44965dfecf96Smrg} 44975dfecf96Smrg 44985dfecf96Smrg 44995dfecf96Smrg/************************************************************************ 45005dfecf96Smrg * BIGNUM BIGRATIO 45015dfecf96Smrg ************************************************************************/ 45025dfecf96Smrgstatic void 45035dfecf96Smrgrop_bi_br_as_xr(n_real *real, mpr *bigratio, int nop) 45045dfecf96Smrg{ 45055dfecf96Smrg mpi iop; 45065dfecf96Smrg mpr *bigr = XALLOC(mpr); 45075dfecf96Smrg 45085dfecf96Smrg mpi_init(&iop); 45095dfecf96Smrg mpi_set(&iop, RBI(real)); 45105dfecf96Smrg mpr_init(bigr); 45115dfecf96Smrg mpr_set(bigr, bigratio); 45125dfecf96Smrg 45135dfecf96Smrg mpi_mul(&iop, &iop, mpr_den(bigratio)); 45145dfecf96Smrg 45155dfecf96Smrg if (nop == NOP_ADD) 45165dfecf96Smrg mpi_add(mpr_num(bigr), &iop, mpr_num(bigr)); 45175dfecf96Smrg else 45185dfecf96Smrg mpi_sub(mpr_num(bigr), &iop, mpr_num(bigr)); 45195dfecf96Smrg mpi_clear(&iop); 45205dfecf96Smrg 45215dfecf96Smrg RCLEAR_BI(real); 45225dfecf96Smrg RBR(real) = bigr; 45235dfecf96Smrg RTYPE(real) = N_BIGRATIO; 45245dfecf96Smrg rbr_canonicalize(real); 45255dfecf96Smrg} 45265dfecf96Smrg 45275dfecf96Smrgstatic void 45285dfecf96Smrgrop_bi_br_md_xr(n_real *real, mpr *bigratio, int nop) 45295dfecf96Smrg{ 45305dfecf96Smrg mpr *bigr = XALLOC(mpr); 45315dfecf96Smrg 45325dfecf96Smrg mpr_init(bigr); 45335dfecf96Smrg if (nop == NOP_MUL) 45345dfecf96Smrg mpr_set(bigr, bigratio); 45355dfecf96Smrg else 45365dfecf96Smrg mpr_inv(bigr, bigratio); 45375dfecf96Smrg 45385dfecf96Smrg mpi_mul(mpr_num(bigr), RBI(real), mpr_num(bigr)); 45395dfecf96Smrg 45405dfecf96Smrg RCLEAR_BI(real); 45415dfecf96Smrg RBR(real) = bigr; 45425dfecf96Smrg RTYPE(real) = N_BIGRATIO; 45435dfecf96Smrg rbr_canonicalize(real); 45445dfecf96Smrg} 45455dfecf96Smrg 45465dfecf96Smrgstatic INLINE void 45475dfecf96Smrgradd_bi_br(n_real *real, mpr *bigratio) 45485dfecf96Smrg{ 45495dfecf96Smrg rop_bi_br_as_xr(real, bigratio, NOP_ADD); 45505dfecf96Smrg} 45515dfecf96Smrg 45525dfecf96Smrgstatic INLINE void 45535dfecf96Smrgrsub_bi_br(n_real *real, mpr *bigratio) 45545dfecf96Smrg{ 45555dfecf96Smrg rop_bi_br_as_xr(real, bigratio, NOP_SUB); 45565dfecf96Smrg} 45575dfecf96Smrg 45585dfecf96Smrgstatic INLINE void 45595dfecf96Smrgrmul_bi_br(n_real *real, mpr *bigratio) 45605dfecf96Smrg{ 45615dfecf96Smrg rop_bi_br_md_xr(real, bigratio, NOP_MUL); 45625dfecf96Smrg} 45635dfecf96Smrg 45645dfecf96Smrgstatic INLINE void 45655dfecf96Smrgrdiv_bi_br(n_real *real, mpr *bigratio) 45665dfecf96Smrg{ 45675dfecf96Smrg rop_bi_br_md_xr(real, bigratio, NOP_DIV); 45685dfecf96Smrg} 45695dfecf96Smrg 45705dfecf96Smrgstatic int 45715dfecf96Smrgcmp_bi_br(mpi *bignum, mpr *bigratio) 45725dfecf96Smrg{ 45735dfecf96Smrg int cmp; 45745dfecf96Smrg mpr cmp1; 45755dfecf96Smrg 45765dfecf96Smrg mpr_init(&cmp1); 45775dfecf96Smrg mpi_set(mpr_num(&cmp1), bignum); 45785dfecf96Smrg mpi_seti(mpr_den(&cmp1), 1); 45795dfecf96Smrg 45805dfecf96Smrg cmp = mpr_cmp(&cmp1, bigratio); 45815dfecf96Smrg mpr_clear(&cmp1); 45825dfecf96Smrg 45835dfecf96Smrg return (cmp); 45845dfecf96Smrg} 45855dfecf96Smrg 45865dfecf96Smrg 45875dfecf96Smrg/************************************************************************ 45885dfecf96Smrg * FIXRATIO FIXNUM 45895dfecf96Smrg ************************************************************************/ 45905dfecf96Smrgstatic void 45915dfecf96Smrgrop_fr_fi_as_xr(n_real *real, long op, int nop) 45925dfecf96Smrg{ 45935dfecf96Smrg int fit; 45945dfecf96Smrg long value = 0, num = RFRN(real), den = RFRD(real); 45955dfecf96Smrg 45965dfecf96Smrg fit = !fi_fi_mul_overflow(op, den); 45975dfecf96Smrg 45985dfecf96Smrg if (fit) { 45995dfecf96Smrg value = op * den; 46005dfecf96Smrg if (nop == NOP_ADD) 46015dfecf96Smrg fit = !fi_fi_add_overflow(value, num); 46025dfecf96Smrg else 46035dfecf96Smrg fit = !fi_fi_sub_overflow(value, num); 46045dfecf96Smrg } 46055dfecf96Smrg if (fit) { 46065dfecf96Smrg if (nop == NOP_ADD) 46075dfecf96Smrg RFRN(real) = num + value; 46085dfecf96Smrg else 46095dfecf96Smrg RFRN(real) = num - value; 46105dfecf96Smrg rfr_canonicalize(real); 46115dfecf96Smrg } 46125dfecf96Smrg else { 46135dfecf96Smrg mpi iop; 46145dfecf96Smrg mpr *bigr = XALLOC(mpr); 46155dfecf96Smrg 46165dfecf96Smrg mpr_init(bigr); 46175dfecf96Smrg mpr_seti(bigr, num, den); 46185dfecf96Smrg mpi_init(&iop); 46195dfecf96Smrg mpi_seti(&iop, op); 46205dfecf96Smrg mpi_muli(&iop, &iop, den); 46215dfecf96Smrg if (nop == NOP_ADD) 46225dfecf96Smrg mpi_add(mpr_num(bigr), mpr_num(bigr), &iop); 46235dfecf96Smrg else 46245dfecf96Smrg mpi_sub(mpr_num(bigr), mpr_num(bigr), &iop); 46255dfecf96Smrg mpi_clear(&iop); 46265dfecf96Smrg RBR(real) = bigr; 46275dfecf96Smrg RTYPE(real) = N_BIGRATIO; 46285dfecf96Smrg rbr_canonicalize(real); 46295dfecf96Smrg } 46305dfecf96Smrg} 46315dfecf96Smrg 46325dfecf96Smrgstatic void 46335dfecf96Smrgrop_fr_fi_md_xr(n_real *real, long op, int nop) 46345dfecf96Smrg{ 46355dfecf96Smrg long num = RFRN(real), den = RFRD(real); 46365dfecf96Smrg 46375dfecf96Smrg if (nop == NOP_MUL) { 46385dfecf96Smrg if (!fi_fi_mul_overflow(op, num)) { 46395dfecf96Smrg RFRN(real) = op * num; 46405dfecf96Smrg rfr_canonicalize(real); 46415dfecf96Smrg return; 46425dfecf96Smrg } 46435dfecf96Smrg } 46445dfecf96Smrg else if (!fi_fi_mul_overflow(op, den)) { 46455dfecf96Smrg RFRD(real) = op * den; 46465dfecf96Smrg rfr_canonicalize(real); 46475dfecf96Smrg return; 46485dfecf96Smrg } 46495dfecf96Smrg 46505dfecf96Smrg { 46515dfecf96Smrg mpr *bigr = XALLOC(mpr); 46525dfecf96Smrg 46535dfecf96Smrg mpr_init(bigr); 46545dfecf96Smrg mpr_seti(bigr, num, den); 46555dfecf96Smrg if (nop == NOP_MUL) 46565dfecf96Smrg mpr_muli(bigr, bigr, op); 46575dfecf96Smrg else 46585dfecf96Smrg mpr_divi(bigr, bigr, op); 46595dfecf96Smrg RBR(real) = bigr; 46605dfecf96Smrg RTYPE(real) = N_BIGRATIO; 46615dfecf96Smrg rbr_canonicalize(real); 46625dfecf96Smrg } 46635dfecf96Smrg} 46645dfecf96Smrg 46655dfecf96Smrgstatic INLINE void 46665dfecf96Smrgradd_fr_fi(n_real *real, long op) 46675dfecf96Smrg{ 46685dfecf96Smrg rop_fr_fi_as_xr(real, op, NOP_ADD); 46695dfecf96Smrg} 46705dfecf96Smrg 46715dfecf96Smrgstatic INLINE void 46725dfecf96Smrgrsub_fr_fi(n_real *real, long op) 46735dfecf96Smrg{ 46745dfecf96Smrg rop_fr_fi_as_xr(real, op, NOP_SUB); 46755dfecf96Smrg} 46765dfecf96Smrg 46775dfecf96Smrgstatic INLINE void 46785dfecf96Smrgrmul_fr_fi(n_real *real, long op) 46795dfecf96Smrg{ 46805dfecf96Smrg rop_fr_fi_md_xr(real, op, NOP_MUL); 46815dfecf96Smrg} 46825dfecf96Smrg 46835dfecf96Smrgstatic INLINE void 46845dfecf96Smrgrdiv_fr_fi(n_real *real, long op) 46855dfecf96Smrg{ 46865dfecf96Smrg rop_fr_fi_md_xr(real, op, NOP_DIV); 46875dfecf96Smrg} 46885dfecf96Smrg 46895dfecf96Smrgstatic INLINE int 46905dfecf96Smrgcmp_fr_fi(long num, long den, long fixnum) 46915dfecf96Smrg{ 46925dfecf96Smrg return (cmp_flonum((double)num / (double)den, (double)fixnum)); 46935dfecf96Smrg} 46945dfecf96Smrg 46955dfecf96Smrg 46965dfecf96Smrg/************************************************************************ 46975dfecf96Smrg * FIXRATIO BIGNUM 46985dfecf96Smrg ************************************************************************/ 46995dfecf96Smrgstatic void 47005dfecf96Smrgrop_fr_bi_as_xr(n_real *real, mpi *bignum, int nop) 47015dfecf96Smrg{ 47025dfecf96Smrg mpi iop; 47035dfecf96Smrg mpr *bigr = XALLOC(mpr); 47045dfecf96Smrg 47055dfecf96Smrg mpr_init(bigr); 47065dfecf96Smrg mpr_seti(bigr, RFRN(real), RFRD(real)); 47075dfecf96Smrg 47085dfecf96Smrg mpi_init(&iop); 47095dfecf96Smrg mpi_set(&iop, bignum); 47105dfecf96Smrg mpi_muli(&iop, &iop, RFRD(real)); 47115dfecf96Smrg 47125dfecf96Smrg if (nop == NOP_ADD) 47135dfecf96Smrg mpi_add(mpr_num(bigr), mpr_num(bigr), &iop); 47145dfecf96Smrg else 47155dfecf96Smrg mpi_sub(mpr_num(bigr), mpr_num(bigr), &iop); 47165dfecf96Smrg mpi_clear(&iop); 47175dfecf96Smrg 47185dfecf96Smrg RBR(real) = bigr; 47195dfecf96Smrg RTYPE(real) = N_BIGRATIO; 47205dfecf96Smrg rbr_canonicalize(real); 47215dfecf96Smrg} 47225dfecf96Smrg 47235dfecf96Smrgstatic void 47245dfecf96Smrgrop_fr_bi_md_xr(n_real *real, mpi *bignum, int nop) 47255dfecf96Smrg{ 47265dfecf96Smrg mpr *bigr = XALLOC(mpr); 47275dfecf96Smrg 47285dfecf96Smrg mpr_init(bigr); 47295dfecf96Smrg mpr_seti(bigr, RFRN(real), RFRD(real)); 47305dfecf96Smrg 47315dfecf96Smrg if (nop == NOP_MUL) 47325dfecf96Smrg mpi_mul(mpr_num(bigr), mpr_num(bigr), bignum); 47335dfecf96Smrg else 47345dfecf96Smrg mpi_mul(mpr_den(bigr), mpr_den(bigr), bignum); 47355dfecf96Smrg 47365dfecf96Smrg RBR(real) = bigr; 47375dfecf96Smrg RTYPE(real) = N_BIGRATIO; 47385dfecf96Smrg rbr_canonicalize(real); 47395dfecf96Smrg} 47405dfecf96Smrg 47415dfecf96Smrgstatic INLINE void 47425dfecf96Smrgradd_fr_bi(n_real *real, mpi *bignum) 47435dfecf96Smrg{ 47445dfecf96Smrg rop_fr_bi_as_xr(real, bignum, NOP_ADD); 47455dfecf96Smrg} 47465dfecf96Smrg 47475dfecf96Smrgstatic INLINE void 47485dfecf96Smrgrsub_fr_bi(n_real *real, mpi *bignum) 47495dfecf96Smrg{ 47505dfecf96Smrg rop_fr_bi_as_xr(real, bignum, NOP_SUB); 47515dfecf96Smrg} 47525dfecf96Smrg 47535dfecf96Smrgstatic INLINE void 47545dfecf96Smrgrmul_fr_bi(n_real *real, mpi *bignum) 47555dfecf96Smrg{ 47565dfecf96Smrg rop_fr_bi_md_xr(real, bignum, NOP_MUL); 47575dfecf96Smrg} 47585dfecf96Smrg 47595dfecf96Smrgstatic INLINE void 47605dfecf96Smrgrdiv_fr_bi(n_real *real, mpi *bignum) 47615dfecf96Smrg{ 47625dfecf96Smrg rop_fr_bi_md_xr(real, bignum, NOP_DIV); 47635dfecf96Smrg} 47645dfecf96Smrg 47655dfecf96Smrgstatic int 47665dfecf96Smrgcmp_fr_bi(long num, long den, mpi *bignum) 47675dfecf96Smrg{ 47685dfecf96Smrg int cmp; 47695dfecf96Smrg mpr cmp1, cmp2; 47705dfecf96Smrg 47715dfecf96Smrg mpr_init(&cmp1); 47725dfecf96Smrg mpr_seti(&cmp1, num, den); 47735dfecf96Smrg 47745dfecf96Smrg mpr_init(&cmp2); 47755dfecf96Smrg mpi_set(mpr_num(&cmp2), bignum); 47765dfecf96Smrg mpi_seti(mpr_den(&cmp2), 1); 47775dfecf96Smrg 47785dfecf96Smrg cmp = mpr_cmp(&cmp1, &cmp2); 47795dfecf96Smrg mpr_clear(&cmp1); 47805dfecf96Smrg mpr_clear(&cmp2); 47815dfecf96Smrg 47825dfecf96Smrg return (cmp); 47835dfecf96Smrg} 47845dfecf96Smrg 47855dfecf96Smrg 47865dfecf96Smrg/************************************************************************ 47875dfecf96Smrg * FIXRATIO FIXRATIO 47885dfecf96Smrg ************************************************************************/ 47895dfecf96Smrgstatic void 47905dfecf96Smrgrop_fr_fr_as_xr(n_real *real, long num2, long den2, int nop) 47915dfecf96Smrg{ 47925dfecf96Smrg int fit; 47935dfecf96Smrg long num1 = RFRN(real), den1 = RFRD(real), num = 0, den = 0; 47945dfecf96Smrg 47955dfecf96Smrg fit = !fi_fi_mul_overflow(num1, den2); 47965dfecf96Smrg if (fit) { 47975dfecf96Smrg num = num1 * den2; 47985dfecf96Smrg fit = !fi_fi_mul_overflow(num2, den1); 47995dfecf96Smrg if (fit) { 48005dfecf96Smrg den = num2 * den1; 48015dfecf96Smrg if (nop == NOP_ADD) { 48025dfecf96Smrg if ((fit = !fi_fi_add_overflow(num, den)) != 0) 48035dfecf96Smrg num += den; 48045dfecf96Smrg } 48055dfecf96Smrg else if ((fit = !fi_fi_sub_overflow(num, den)) != 0) 48065dfecf96Smrg num -= den; 48075dfecf96Smrg if (fit) { 48085dfecf96Smrg fit = !fi_fi_mul_overflow(den1, den2); 48095dfecf96Smrg if (fit) 48105dfecf96Smrg den = den1 * den2; 48115dfecf96Smrg } 48125dfecf96Smrg } 48135dfecf96Smrg } 48145dfecf96Smrg if (fit) { 48155dfecf96Smrg RFRN(real) = num; 48165dfecf96Smrg RFRD(real) = den; 48175dfecf96Smrg rfr_canonicalize(real); 48185dfecf96Smrg } 48195dfecf96Smrg else { 48205dfecf96Smrg mpi iop; 48215dfecf96Smrg mpr *bigr = XALLOC(mpr); 48225dfecf96Smrg 48235dfecf96Smrg mpr_init(bigr); 48245dfecf96Smrg mpr_seti(bigr, num1, den1); 48255dfecf96Smrg mpi_muli(mpr_den(bigr), mpr_den(bigr), den2); 48265dfecf96Smrg mpi_init(&iop); 48275dfecf96Smrg mpi_seti(&iop, num2); 48285dfecf96Smrg mpi_muli(&iop, &iop, den1); 48295dfecf96Smrg mpi_muli(mpr_num(bigr), mpr_num(bigr), den2); 48305dfecf96Smrg if (nop == NOP_ADD) 48315dfecf96Smrg mpi_add(mpr_num(bigr), mpr_num(bigr), &iop); 48325dfecf96Smrg else 48335dfecf96Smrg mpi_sub(mpr_num(bigr), mpr_num(bigr), &iop); 48345dfecf96Smrg mpi_clear(&iop); 48355dfecf96Smrg RBR(real) = bigr; 48365dfecf96Smrg RTYPE(real) = N_BIGRATIO; 48375dfecf96Smrg rbr_canonicalize(real); 48385dfecf96Smrg } 48395dfecf96Smrg} 48405dfecf96Smrg 48415dfecf96Smrgstatic void 48425dfecf96Smrgrop_fr_fr_md_xr(n_real *real, long num2, long den2, int nop) 48435dfecf96Smrg{ 48445dfecf96Smrg int fit; 48455dfecf96Smrg long num1 = RFRN(real), den1 = RFRD(real), num = 0, den = 0; 48465dfecf96Smrg 48475dfecf96Smrg if (nop == NOP_MUL) { 48485dfecf96Smrg fit = !fi_fi_mul_overflow(num1, num2) && !fi_fi_mul_overflow(den1, den2); 48495dfecf96Smrg if (fit) { 48505dfecf96Smrg num = num1 * num2; 48515dfecf96Smrg den = den1 * den2; 48525dfecf96Smrg } 48535dfecf96Smrg } 48545dfecf96Smrg else { 48555dfecf96Smrg fit = !fi_fi_mul_overflow(num1, den2) && !fi_fi_mul_overflow(den1, num2); 48565dfecf96Smrg if (fit) { 48575dfecf96Smrg num = num1 * den2; 48585dfecf96Smrg den = den1 * num2; 48595dfecf96Smrg } 48605dfecf96Smrg } 48615dfecf96Smrg 48625dfecf96Smrg if (fit) { 48635dfecf96Smrg RFRN(real) = num; 48645dfecf96Smrg RFRD(real) = den; 48655dfecf96Smrg rfr_canonicalize(real); 48665dfecf96Smrg } 48675dfecf96Smrg else { 48685dfecf96Smrg mpr *bigr = XALLOC(mpr); 48695dfecf96Smrg 48705dfecf96Smrg mpr_init(bigr); 48715dfecf96Smrg 48725dfecf96Smrg if (nop == NOP_MUL) { 48735dfecf96Smrg mpr_seti(bigr, num1, den1); 48745dfecf96Smrg mpi_muli(mpr_num(bigr), mpr_num(bigr), num2); 48755dfecf96Smrg mpi_muli(mpr_den(bigr), mpr_den(bigr), den2); 48765dfecf96Smrg } 48775dfecf96Smrg else { 48785dfecf96Smrg mpr_seti(bigr, num1, num2); 48795dfecf96Smrg mpi_muli(mpr_num(bigr), mpr_num(bigr), den2); 48805dfecf96Smrg mpi_muli(mpr_den(bigr), mpr_den(bigr), den1); 48815dfecf96Smrg } 48825dfecf96Smrg 48835dfecf96Smrg RBR(real) = bigr; 48845dfecf96Smrg RTYPE(real) = N_BIGRATIO; 48855dfecf96Smrg rbr_canonicalize(real); 48865dfecf96Smrg } 48875dfecf96Smrg} 48885dfecf96Smrg 48895dfecf96Smrgstatic INLINE void 48905dfecf96Smrgradd_fr_fr(n_real *real, long num, long den) 48915dfecf96Smrg{ 48925dfecf96Smrg rop_fr_fr_as_xr(real, num, den, NOP_ADD); 48935dfecf96Smrg} 48945dfecf96Smrg 48955dfecf96Smrgstatic INLINE void 48965dfecf96Smrgrsub_fr_fr(n_real *real, long num, long den) 48975dfecf96Smrg{ 48985dfecf96Smrg rop_fr_fr_as_xr(real, num, den, NOP_SUB); 48995dfecf96Smrg} 49005dfecf96Smrg 49015dfecf96Smrgstatic INLINE void 49025dfecf96Smrgrmul_fr_fr(n_real *real, long num, long den) 49035dfecf96Smrg{ 49045dfecf96Smrg rop_fr_fr_md_xr(real, num, den, NOP_MUL); 49055dfecf96Smrg} 49065dfecf96Smrg 49075dfecf96Smrgstatic INLINE void 49085dfecf96Smrgrdiv_fr_fr(n_real *real, long num, long den) 49095dfecf96Smrg{ 49105dfecf96Smrg rop_fr_fr_md_xr(real, num, den, NOP_DIV); 49115dfecf96Smrg} 49125dfecf96Smrg 49135dfecf96Smrgstatic INLINE int 49145dfecf96Smrgcmp_fr_fr(long num1, long den1, long num2, long den2) 49155dfecf96Smrg{ 49165dfecf96Smrg return (cmp_flonum((double)num1 / (double)den1, 49175dfecf96Smrg (double)num2 / (double)den2)); 49185dfecf96Smrg} 49195dfecf96Smrg 49205dfecf96Smrg 49215dfecf96Smrg/************************************************************************ 49225dfecf96Smrg * FIXRATIO BIGRATIO 49235dfecf96Smrg ************************************************************************/ 49245dfecf96Smrgstatic void 49255dfecf96Smrgrop_fr_br_asmd_xr(n_real *real, mpr *bigratio, int nop) 49265dfecf96Smrg{ 49275dfecf96Smrg mpr *bigr = XALLOC(mpr); 49285dfecf96Smrg 49295dfecf96Smrg mpr_init(bigr); 49305dfecf96Smrg mpr_seti(bigr, RFRN(real), RFRD(real)); 49315dfecf96Smrg 49325dfecf96Smrg switch (nop) { 49335dfecf96Smrg case NOP_ADD: 49345dfecf96Smrg mpr_add(bigr, bigr, bigratio); 49355dfecf96Smrg break; 49365dfecf96Smrg case NOP_SUB: 49375dfecf96Smrg mpr_sub(bigr, bigr, bigratio); 49385dfecf96Smrg break; 49395dfecf96Smrg case NOP_MUL: 49405dfecf96Smrg mpr_mul(bigr, bigr, bigratio); 49415dfecf96Smrg break; 49425dfecf96Smrg default: 49435dfecf96Smrg mpr_div(bigr, bigr, bigratio); 49445dfecf96Smrg break; 49455dfecf96Smrg } 49465dfecf96Smrg 49475dfecf96Smrg RBR(real) = bigr; 49485dfecf96Smrg RTYPE(real) = N_BIGRATIO; 49495dfecf96Smrg rbr_canonicalize(real); 49505dfecf96Smrg} 49515dfecf96Smrg 49525dfecf96Smrgstatic INLINE void 49535dfecf96Smrgradd_fr_br(n_real *real, mpr *bigratio) 49545dfecf96Smrg{ 49555dfecf96Smrg rop_fr_br_asmd_xr(real, bigratio, NOP_ADD); 49565dfecf96Smrg} 49575dfecf96Smrg 49585dfecf96Smrgstatic INLINE void 49595dfecf96Smrgrsub_fr_br(n_real *real, mpr *bigratio) 49605dfecf96Smrg{ 49615dfecf96Smrg rop_fr_br_asmd_xr(real, bigratio, NOP_SUB); 49625dfecf96Smrg} 49635dfecf96Smrg 49645dfecf96Smrgstatic INLINE void 49655dfecf96Smrgrmul_fr_br(n_real *real, mpr *bigratio) 49665dfecf96Smrg{ 49675dfecf96Smrg rop_fr_br_asmd_xr(real, bigratio, NOP_MUL); 49685dfecf96Smrg} 49695dfecf96Smrg 49705dfecf96Smrgstatic INLINE void 49715dfecf96Smrgrdiv_fr_br(n_real *real, mpr *bigratio) 49725dfecf96Smrg{ 49735dfecf96Smrg rop_fr_br_asmd_xr(real, bigratio, NOP_DIV); 49745dfecf96Smrg} 49755dfecf96Smrg 49765dfecf96Smrgstatic int 49775dfecf96Smrgcmp_fr_br(long num, long den, mpr *bigratio) 49785dfecf96Smrg{ 49795dfecf96Smrg int cmp; 49805dfecf96Smrg mpr cmp1; 49815dfecf96Smrg 49825dfecf96Smrg mpr_init(&cmp1); 49835dfecf96Smrg mpr_seti(&cmp1, num, den); 49845dfecf96Smrg 49855dfecf96Smrg cmp = mpr_cmp(&cmp1, bigratio); 49865dfecf96Smrg mpr_clear(&cmp1); 49875dfecf96Smrg 49885dfecf96Smrg return (cmp); 49895dfecf96Smrg} 49905dfecf96Smrg 49915dfecf96Smrg 49925dfecf96Smrg/************************************************************************ 49935dfecf96Smrg * BIGRATIO FIXNUM 49945dfecf96Smrg ************************************************************************/ 49955dfecf96Smrgstatic void 49965dfecf96Smrgrop_br_fi_asmd_xr(n_real *real, long fixnum, int nop) 49975dfecf96Smrg{ 49985dfecf96Smrg mpr *bigratio = RBR(real); 49995dfecf96Smrg 50005dfecf96Smrg switch (nop) { 50015dfecf96Smrg case NOP_ADD: 50025dfecf96Smrg mpr_addi(bigratio, bigratio, fixnum); 50035dfecf96Smrg break; 50045dfecf96Smrg case NOP_SUB: 50055dfecf96Smrg mpr_subi(bigratio, bigratio, fixnum); 50065dfecf96Smrg break; 50075dfecf96Smrg case NOP_MUL: 50085dfecf96Smrg mpr_muli(bigratio, bigratio, fixnum); 50095dfecf96Smrg break; 50105dfecf96Smrg default: 50115dfecf96Smrg if (fixnum == 0) 50125dfecf96Smrg fatal_error(DIVIDE_BY_ZERO); 50135dfecf96Smrg mpr_divi(bigratio, bigratio, fixnum); 50145dfecf96Smrg break; 50155dfecf96Smrg } 50165dfecf96Smrg rbr_canonicalize(real); 50175dfecf96Smrg} 50185dfecf96Smrg 50195dfecf96Smrgstatic INLINE void 50205dfecf96Smrgradd_br_fi(n_real *real, long fixnum) 50215dfecf96Smrg{ 50225dfecf96Smrg rop_br_fi_asmd_xr(real, fixnum, NOP_ADD); 50235dfecf96Smrg} 50245dfecf96Smrg 50255dfecf96Smrgstatic INLINE void 50265dfecf96Smrgrsub_br_fi(n_real *real, long fixnum) 50275dfecf96Smrg{ 50285dfecf96Smrg rop_br_fi_asmd_xr(real, fixnum, NOP_SUB); 50295dfecf96Smrg} 50305dfecf96Smrg 50315dfecf96Smrgstatic INLINE void 50325dfecf96Smrgrmul_br_fi(n_real *real, long fixnum) 50335dfecf96Smrg{ 50345dfecf96Smrg rop_br_fi_asmd_xr(real, fixnum, NOP_MUL); 50355dfecf96Smrg} 50365dfecf96Smrg 50375dfecf96Smrgstatic INLINE void 50385dfecf96Smrgrdiv_br_fi(n_real *real, long fixnum) 50395dfecf96Smrg{ 50405dfecf96Smrg rop_br_fi_asmd_xr(real, fixnum, NOP_DIV); 50415dfecf96Smrg} 50425dfecf96Smrg 50435dfecf96Smrgstatic int 50445dfecf96Smrgcmp_br_fi(mpr *bigratio, long fixnum) 50455dfecf96Smrg{ 50465dfecf96Smrg int cmp; 50475dfecf96Smrg mpr cmp2; 50485dfecf96Smrg 50495dfecf96Smrg mpr_init(&cmp2); 50505dfecf96Smrg mpr_seti(&cmp2, fixnum, 1); 50515dfecf96Smrg cmp = mpr_cmp(bigratio, &cmp2); 50525dfecf96Smrg mpr_clear(&cmp2); 50535dfecf96Smrg 50545dfecf96Smrg return (cmp); 50555dfecf96Smrg} 50565dfecf96Smrg 50575dfecf96Smrg 50585dfecf96Smrg/************************************************************************ 50595dfecf96Smrg * BIGRATIO BIGNUM 50605dfecf96Smrg ************************************************************************/ 50615dfecf96Smrgstatic void 50625dfecf96Smrgrop_br_bi_as_xr(n_real *real, mpi *bignum, int nop) 50635dfecf96Smrg{ 50645dfecf96Smrg mpi iop; 50655dfecf96Smrg 50665dfecf96Smrg mpi_init(&iop); 50675dfecf96Smrg mpi_set(&iop, bignum); 50685dfecf96Smrg 50695dfecf96Smrg mpi_mul(&iop, &iop, RBRD(real)); 50705dfecf96Smrg if (nop == NOP_ADD) 50715dfecf96Smrg mpi_add(RBRN(real), RBRN(real), &iop); 50725dfecf96Smrg else 50735dfecf96Smrg mpi_sub(RBRN(real), RBRN(real), &iop); 50745dfecf96Smrg mpi_clear(&iop); 50755dfecf96Smrg rbr_canonicalize(real); 50765dfecf96Smrg} 50775dfecf96Smrg 50785dfecf96Smrgstatic INLINE void 50795dfecf96Smrgradd_br_bi(n_real *real, mpi *bignum) 50805dfecf96Smrg{ 50815dfecf96Smrg rop_br_bi_as_xr(real, bignum, NOP_ADD); 50825dfecf96Smrg} 50835dfecf96Smrg 50845dfecf96Smrgstatic INLINE void 50855dfecf96Smrgrsub_br_bi(n_real *real, mpi *bignum) 50865dfecf96Smrg{ 50875dfecf96Smrg rop_br_bi_as_xr(real, bignum, NOP_SUB); 50885dfecf96Smrg} 50895dfecf96Smrg 50905dfecf96Smrgstatic INLINE void 50915dfecf96Smrgrmul_br_bi(n_real *real, mpi *bignum) 50925dfecf96Smrg{ 50935dfecf96Smrg mpi_mul(RBRN(real), RBRN(real), bignum); 50945dfecf96Smrg rbr_canonicalize(real); 50955dfecf96Smrg} 50965dfecf96Smrg 50975dfecf96Smrgstatic INLINE void 50985dfecf96Smrgrdiv_br_bi(n_real *real, mpi *bignum) 50995dfecf96Smrg{ 51005dfecf96Smrg mpi_mul(RBRD(real), RBRD(real), bignum); 51015dfecf96Smrg rbr_canonicalize(real); 51025dfecf96Smrg} 51035dfecf96Smrg 51045dfecf96Smrgstatic int 51055dfecf96Smrgcmp_br_bi(mpr *bigratio, mpi *bignum) 51065dfecf96Smrg{ 51075dfecf96Smrg int cmp; 51085dfecf96Smrg mpr cmp1; 51095dfecf96Smrg 51105dfecf96Smrg mpr_init(&cmp1); 51115dfecf96Smrg mpi_set(mpr_num(&cmp1), bignum); 51125dfecf96Smrg mpi_seti(mpr_den(&cmp1), 1); 51135dfecf96Smrg 51145dfecf96Smrg cmp = mpr_cmp(bigratio, &cmp1); 51155dfecf96Smrg mpr_clear(&cmp1); 51165dfecf96Smrg 51175dfecf96Smrg return (cmp); 51185dfecf96Smrg} 51195dfecf96Smrg 51205dfecf96Smrg 51215dfecf96Smrg/************************************************************************ 51225dfecf96Smrg * BIGRATIO FIXRATIO 51235dfecf96Smrg ************************************************************************/ 51245dfecf96Smrgstatic void 51255dfecf96Smrgrop_br_fr_asmd_xr(n_real *real, long num, long den, int nop) 51265dfecf96Smrg{ 51275dfecf96Smrg mpr *bigratio = RBR(real), rop; 51285dfecf96Smrg 51295dfecf96Smrg mpr_init(&rop); 51305dfecf96Smrg mpr_seti(&rop, num, den); 51315dfecf96Smrg switch (nop) { 51325dfecf96Smrg case NOP_ADD: 51335dfecf96Smrg mpr_add(bigratio, bigratio, &rop); 51345dfecf96Smrg break; 51355dfecf96Smrg case NOP_SUB: 51365dfecf96Smrg mpr_sub(bigratio, bigratio, &rop); 51375dfecf96Smrg break; 51385dfecf96Smrg case NOP_MUL: 51395dfecf96Smrg mpr_mul(bigratio, bigratio, &rop); 51405dfecf96Smrg break; 51415dfecf96Smrg default: 51425dfecf96Smrg mpr_div(bigratio, bigratio, &rop); 51435dfecf96Smrg break; 51445dfecf96Smrg } 51455dfecf96Smrg mpr_clear(&rop); 51465dfecf96Smrg rbr_canonicalize(real); 51475dfecf96Smrg} 51485dfecf96Smrg 51495dfecf96Smrgstatic INLINE void 51505dfecf96Smrgradd_br_fr(n_real *real, long num, long den) 51515dfecf96Smrg{ 51525dfecf96Smrg rop_br_fr_asmd_xr(real, num, den, NOP_ADD); 51535dfecf96Smrg} 51545dfecf96Smrg 51555dfecf96Smrgstatic INLINE void 51565dfecf96Smrgrsub_br_fr(n_real *real, long num, long den) 51575dfecf96Smrg{ 51585dfecf96Smrg rop_br_fr_asmd_xr(real, num, den, NOP_SUB); 51595dfecf96Smrg} 51605dfecf96Smrg 51615dfecf96Smrgstatic INLINE void 51625dfecf96Smrgrmul_br_fr(n_real *real, long num, long den) 51635dfecf96Smrg{ 51645dfecf96Smrg rop_br_fr_asmd_xr(real, num, den, NOP_MUL); 51655dfecf96Smrg} 51665dfecf96Smrg 51675dfecf96Smrgstatic INLINE void 51685dfecf96Smrgrdiv_br_fr(n_real *real, long num, long den) 51695dfecf96Smrg{ 51705dfecf96Smrg rop_br_fr_asmd_xr(real, num, den, NOP_DIV); 51715dfecf96Smrg} 51725dfecf96Smrg 51735dfecf96Smrgstatic int 51745dfecf96Smrgcmp_br_fr(mpr *bigratio, long num, long den) 51755dfecf96Smrg{ 51765dfecf96Smrg int cmp; 51775dfecf96Smrg mpr cmp2; 51785dfecf96Smrg 51795dfecf96Smrg mpr_init(&cmp2); 51805dfecf96Smrg mpr_seti(&cmp2, num, den); 51815dfecf96Smrg cmp = mpr_cmp(bigratio, &cmp2); 51825dfecf96Smrg mpr_clear(&cmp2); 51835dfecf96Smrg 51845dfecf96Smrg return (cmp); 51855dfecf96Smrg} 51865dfecf96Smrg 51875dfecf96Smrg 51885dfecf96Smrg/************************************************************************ 51895dfecf96Smrg * BIGRATIO BIGRATIO 51905dfecf96Smrg ************************************************************************/ 51915dfecf96Smrgstatic INLINE void 51925dfecf96Smrgradd_br_br(n_real *real, mpr *bigratio) 51935dfecf96Smrg{ 51945dfecf96Smrg mpr_add(RBR(real), RBR(real), bigratio); 51955dfecf96Smrg rbr_canonicalize(real); 51965dfecf96Smrg} 51975dfecf96Smrg 51985dfecf96Smrgstatic INLINE void 51995dfecf96Smrgrsub_br_br(n_real *real, mpr *bigratio) 52005dfecf96Smrg{ 52015dfecf96Smrg mpr_sub(RBR(real), RBR(real), bigratio); 52025dfecf96Smrg rbr_canonicalize(real); 52035dfecf96Smrg} 52045dfecf96Smrg 52055dfecf96Smrgstatic INLINE void 52065dfecf96Smrgrmul_br_br(n_real *real, mpr *bigratio) 52075dfecf96Smrg{ 52085dfecf96Smrg mpr_mul(RBR(real), RBR(real), bigratio); 52095dfecf96Smrg rbr_canonicalize(real); 52105dfecf96Smrg} 52115dfecf96Smrg 52125dfecf96Smrgstatic INLINE void 52135dfecf96Smrgrdiv_br_br(n_real *real, mpr *bigratio) 52145dfecf96Smrg{ 52155dfecf96Smrg mpr_div(RBR(real), RBR(real), bigratio); 52165dfecf96Smrg rbr_canonicalize(real); 52175dfecf96Smrg} 52185dfecf96Smrg 52195dfecf96Smrgstatic INLINE int 52205dfecf96Smrgcmp_br_br(mpr *op1, mpr *op2) 52215dfecf96Smrg{ 52225dfecf96Smrg return (mpr_cmp(op1, op2)); 52235dfecf96Smrg} 5224