int scheme_rational_eq(const Scheme_Object *a, const Scheme_Object *b) { Scheme_Rational *ra = (Scheme_Rational *)a; Scheme_Rational *rb = (Scheme_Rational *)b; if (SCHEME_INTP(ra->num) && SCHEME_INTP(rb->num)) { if (ra->num != rb->num) return 0; } else if (SCHEME_BIGNUMP(ra->num) && SCHEME_BIGNUMP(rb->num)) { if (!scheme_bignum_eq(ra->num, rb->num)) return 0; } else return 0; if (SCHEME_INTP(ra->denom) && SCHEME_INTP(rb->denom)) { if (ra->denom != rb->denom) return 0; } else if (SCHEME_BIGNUMP(ra->denom) && SCHEME_BIGNUMP(rb->denom)) { if (!scheme_bignum_eq(ra->denom, rb->denom)) return 0; } else return 0; return 1; }
static Scheme_Object * integer_to_char (int argc, Scheme_Object *argv[]) { if (SCHEME_INTP(argv[0])) { long v; v = SCHEME_INT_VAL(argv[0]); if ((v >= 0) && (v <= 0x10FFFF) && ((v < 0xD800) || (v > 0xDFFF))) return _scheme_make_char(v); } else if (SCHEME_BIGNUMP(argv[0]) && SCHEME_BIGPOS(argv[0])) { /* On 32-bit machines, there's still a chance... */ long y; if (scheme_get_int_val(argv[0], &y)) { if (y <= 0x10FFFF) return _scheme_make_char(y); } } scheme_wrong_type("integer->char", "exact integer in [0,#x10FFFF], not in [#xD800,#xDFFF]", 0, argc, argv); return NULL; }
static Scheme_Object * integer_to_char (int argc, Scheme_Object *argv[]) { if (SCHEME_INTP(argv[0])) { intptr_t v; v = SCHEME_INT_VAL(argv[0]); if ((v >= 0) && (v <= 0x10FFFF) && ((v < 0xD800) || (v > 0xDFFF))) return _scheme_make_char((int)v); } else if (SCHEME_BIGNUMP(argv[0]) && SCHEME_BIGPOS(argv[0])) { /* On 32-bit machines, there's still a chance... */ intptr_t y; if (scheme_get_int_val(argv[0], &y)) { if (y <= 0x10FFFF) return _scheme_make_char((int)y); } } scheme_wrong_contract("integer->char", "(and/c (integer-in 0 #x10FFFF) (not/c (integer-in #xD800 #xDFFF)))", 0, argc, argv); return NULL; }
Scheme_Object *scheme_rational_round(const Scheme_Object *o) { Scheme_Rational *r = (Scheme_Rational *)o; Scheme_Object *q, *qd, *delta, *half; int more = 0, can_eq_half, negative; negative = !scheme_is_rational_positive(o); q = scheme_bin_quotient(r->num, r->denom); /* Get remainder absolute value: */ qd = scheme_bin_mult(q, r->denom); if (negative) delta = scheme_bin_minus(qd, r->num); else delta = scheme_bin_minus(r->num, qd); half = scheme_bin_quotient(r->denom, scheme_make_integer(2)); can_eq_half = SCHEME_FALSEP(scheme_odd_p(1, &r->denom)); if (SCHEME_INTP(half) && SCHEME_INTP(delta)) { if (can_eq_half && (SCHEME_INT_VAL(delta) == SCHEME_INT_VAL(half))) more = SCHEME_TRUEP(scheme_odd_p(1, &q)); else more = (SCHEME_INT_VAL(delta) > SCHEME_INT_VAL(half)); } else if (SCHEME_BIGNUMP(delta) && SCHEME_BIGNUMP(half)) { if (can_eq_half && (scheme_bignum_eq(delta, half))) more = SCHEME_TRUEP(scheme_odd_p(1, &q)); else more = !scheme_bignum_lt(delta, half); } else more = SCHEME_BIGNUMP(delta); if (more) { if (negative) q = scheme_sub1(1, &q); else q = scheme_add1(1, &q); } return q; }
static int rational_lt(const Scheme_Object *a, const Scheme_Object *b, int or_eq) { Scheme_Rational *ra = (Scheme_Rational *)a; Scheme_Rational *rb = (Scheme_Rational *)b; Scheme_Object *ma, *mb; ma = scheme_bin_mult(ra->num, rb->denom); mb = scheme_bin_mult(rb->num, ra->denom); if (SCHEME_INTP(ma) && SCHEME_INTP(mb)) { if (or_eq) return (SCHEME_INT_VAL(ma) <= SCHEME_INT_VAL(mb)); else return (SCHEME_INT_VAL(ma) < SCHEME_INT_VAL(mb)); } else if (SCHEME_BIGNUMP(ma) && SCHEME_BIGNUMP(mb)) { if (or_eq) return scheme_bignum_le(ma, mb); else return scheme_bignum_lt(ma, mb); } else if (SCHEME_BIGNUMP(mb)) { return SCHEME_BIGPOS(mb); } else return !SCHEME_BIGPOS(ma); }
Scheme_Object *scheme_complex_power(const Scheme_Object *base, const Scheme_Object *exponent) { Scheme_Complex *cb = (Scheme_Complex *)base; Scheme_Complex *ce = (Scheme_Complex *)exponent; double a, b, c, d, bm, ba, nm, na, r1, r2; int d_is_zero; if ((ce->i == zero) && !SCHEME_FLOATP(ce->r)) { if (SCHEME_INTP(ce->r) || SCHEME_BIGNUMP(ce->r)) return scheme_generic_integer_power(base, ce->r); } a = scheme_get_val_as_double(cb->r); b = scheme_get_val_as_double(cb->i); c = scheme_get_val_as_double(ce->r); d = scheme_get_val_as_double(ce->i); d_is_zero = (ce->i == zero); bm = sqrt(a * a + b * b); ba = atan2(b, a); /* New mag & angle */ nm = scheme_double_expt(bm, c) * exp(-(ba * d)); if (d_is_zero) /* precision here can avoid NaNs */ na = ba * c; else na = log(bm) * d + ba * c; r1 = nm * cos(na); r2 = nm * sin(na); #ifdef MZ_USE_SINGLE_FLOATS /* Coerce to double or float? */ #ifdef USE_SINGLE_FLOATS_AS_DEFAULT if (!SCHEME_DBLP(cb->r) && !SCHEME_DBLP(cb->i) && !SCHEME_DBLP(ce->r) && !SCHEME_DBLP(ce->i)) #else if (SCHEME_FLTP(cb->r) && SCHEME_FLTP(cb->i) && SCHEME_FLTP(ce->r) && SCHEME_FLTP(ce->i)) #endif return scheme_make_complex(scheme_make_float((float)r1), scheme_make_float((float)r2)); #endif return scheme_make_complex(scheme_make_double(r1), scheme_make_double(r2)); }
intptr_t scheme_get_semaphore_init(const char *who, int n, Scheme_Object **p) { intptr_t v; if (n) { if (!SCHEME_INTP(p[0])) { if (!SCHEME_BIGNUMP(p[0]) || !SCHEME_BIGPOS(p[0])) scheme_wrong_contract(who, "exact-nonnegative-integer?", 0, n, p); } if (!scheme_get_int_val(p[0], &v)) { scheme_raise_exn(MZEXN_FAIL, "%s: starting value %s is too large", who, scheme_make_provided_string(p[0], 0, NULL)); } else if (v < 0) scheme_wrong_contract(who, "exact-nonnegative-integer?", 0, n, p); } else v = 0; return v; }
static Scheme_Object * do_list_ref(char *name, int takecar, int argc, Scheme_Object *argv[]) { long i, k; Scheme_Object *lst, *index, *bnindex; if (SCHEME_BIGNUMP(argv[1])) { bnindex = argv[1]; k = 0; } else if (!SCHEME_INTP(argv[1])) { scheme_wrong_type(name, "non-negative exact integer", 1, argc, argv); return NULL; } else { bnindex = NULL; k = SCHEME_INT_VAL(argv[1]); } lst = argv[0]; index = argv[1]; if ((bnindex && !SCHEME_BIGPOS(bnindex)) || (!bnindex && (k < 0))) { scheme_wrong_type(name, "non-negative exact integer", 1, argc, argv); return NULL; } do { if (bnindex) { if (SCHEME_INTP(bnindex)) { k = SCHEME_INT_VAL(bnindex); bnindex = 0; } else { k = LISTREF_BIGNUM_SLICE; bnindex = scheme_bin_minus(bnindex, scheme_make_integer(LISTREF_BIGNUM_SLICE)); } } for (i = 0; i < k; i++) { if (!SCHEME_PAIRP(lst)) { char *lstr; int llen; lstr = scheme_make_provided_string(argv[0], 2, &llen); scheme_raise_exn(MZEXN_FAIL_CONTRACT, "%s: index %s too large for list%s: %t", name, scheme_make_provided_string(index, 2, NULL), SCHEME_NULLP(lst) ? "" : " (not a proper list)", lstr, llen); return NULL; } lst = SCHEME_CDR(lst); if (!(i & OCCASIONAL_CHECK)) SCHEME_USE_FUEL(OCCASIONAL_CHECK); } } while(bnindex); if (takecar) { if (!SCHEME_PAIRP(lst)) { char *lstr; int llen; lstr = scheme_make_provided_string(argv[0], 2, &llen); scheme_raise_exn(MZEXN_FAIL_CONTRACT, "%s: index %s too large for list%s: %t", name, scheme_make_provided_string(index, 2, NULL), SCHEME_NULLP(lst) ? "" : " (not a proper list)", lstr, llen); return NULL; } return SCHEME_CAR(lst); } else return lst; }