20 #if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
25 #define ZERO INT2FIX(0)
26 #define ONE INT2FIX(1)
27 #define TWO INT2FIX(2)
29 #define GMP_GCD_DIGITS 1
37 #define f_boolcast(x) ((x) ? Qtrue : Qfalse)
38 #define f_inspect rb_inspect
39 #define f_to_s rb_obj_as_string
43 f_##n(VALUE x, VALUE y)\
45 return rb_funcall(x, (op), 1, y);\
52 return rb_funcall(x, id_##n, 0);\
57 f_##n(VALUE x, VALUE y)\
59 return rb_funcall(x, id_##n, 1, y);\
167 #define f_expt10(x) f_expt(INT2FIX(10), x)
177 #define f_positive_p(x) (!f_negative_p(x))
196 #define f_nonzero_p(x) (!f_zero_p(x))
266 #define k_exact_p(x) (!k_float_p(x))
267 #define k_inexact_p(x) k_float_p(x)
269 #define k_exact_zero_p(x) (k_exact_p(x) && f_zero_p(x))
270 #define k_exact_one_p(x) (k_exact_p(x) && f_one_p(x))
299 #define f_gcd f_gcd_orig
369 return rb_gcd_gmp(x, y);
381 VALUE r = f_gcd_orig(x, y);
398 #define get_dat1(x) \
399 struct RRational *dat;\
400 dat = ((struct RRational *)(x))
402 #define get_dat2(x,y) \
403 struct RRational *adat, *bdat;\
404 adat = ((struct RRational *)(x));\
405 bdat = ((struct RRational *)(y))
424 #define rb_raise_zerodiv() rb_raise(rb_eZeroDivError, "divided by 0")
466 #ifdef CANONICALIZATION_FOR_MATHN
471 static int canonicalization = 0;
476 canonicalization =
f;
513 gcd =
f_gcd(num, den);
518 if (
f_one_p(den) && canonicalization)
538 if (
f_one_p(den) && canonicalization)
650 #define f_imul f_imul_orig
658 if (a == 0 || b == 0)
678 VALUE r = f_imul_orig(x, y);
695 long ig =
i_gcd(ad, bd);
765 adat->num, adat->den,
766 bdat->num, bdat->den,
'+');
806 adat->num, adat->den,
807 bdat->num, bdat->den,
'-');
838 long g1 =
i_gcd(an, bd);
839 long g2 =
i_gcd(ad, bn);
841 num =
f_imul(an / g1, bn / g2);
842 den =
f_imul(ad / g2, bd / g1);
886 adat->num, adat->den,
887 bdat->num, bdat->den,
'*');
932 bdat->den, bdat->num);
935 adat->num, adat->den,
936 bdat->num, bdat->den,
'/');
1027 num =
f_expt(dat->num, other);
1028 den =
f_expt(dat->den, other);
1043 rb_warn(
"in a**b, b may be too big");
1076 return f_cmp(dat->num, other);
1095 num1 =
f_mul(adat->num, bdat->den);
1096 num2 =
f_mul(bdat->num, adat->den);
1187 return f_idiv(
self, other);
1209 nurat_true(
VALUE self)
1219 return f_idiv(dat->num, dat->den);
1250 return f_idiv(dat->num, dat->den);
1283 return (*
func)(
self);
1425 return f_fdiv(dat->num, dat->den);
1443 #define id_ceil rb_intern("ceil")
1444 #define f_ceil(x) rb_funcall((x), id_ceil, 0)
1446 #define id_quo rb_intern("quo")
1447 #define f_quo(x,y) rb_funcall((x), id_quo, 1, (y))
1449 #define f_reciprocal(x) f_quo(ONE, (x))
1513 VALUE c, k,
t, p0, p1, p2, q0, q1, q2;
1598 s = (*func)(dat->num);
1717 return f_gcd(
self, other);
1735 return f_lcm(
self, other);
1778 #define id_numerator rb_intern("numerator")
1779 #define f_numerator(x) rb_funcall((x), id_numerator, 0)
1781 #define id_denominator rb_intern("denominator")
1782 #define f_denominator(x) rb_funcall((x), id_denominator, 0)
1784 #define id_to_r rb_intern("to_r")
1785 #define f_to_r(x) rb_funcall((x), id_to_r, 0)
1824 return f_fdiv(x, y);
1828 if (canonicalization) {
1971 float_decode(
VALUE self)
1980 #define id_lshift rb_intern("<<")
1981 #define f_lshift(x,n) rb_funcall((x), id_lshift, 1, (n))
2048 VALUE two_times_f, den;
2058 VALUE radix_times_f, den;
2112 return (c ==
'-' || c ==
'+');
2130 return isdigit((
unsigned char)c);
2138 int us = 1,
ret = 1;
2169 }
while (**s ==
'_');
2180 return (c ==
'e' || c ==
'E');
2206 *num =
f_mul(*num, l);
2207 *num =
f_add(*num, fp);
2208 *num =
f_div(*num, l);
2227 *num =
f_mul(*num, l);
2247 if (!
read_num(s, sign, strict, num))
2254 *num =
f_div(*num, den);
2274 while (isspace((
unsigned char)**s))
2390 VALUE a1, a2, backref;
2437 (!f_integer_p(a1) || !f_integer_p(a2)))
2438 return f_div(a1, a2);
2495 #define rb_intern(str) rb_intern_const(str)
2497 assert(fprintf(stderr,
"assert() is now active\n"));
static VALUE numeric_denominator(VALUE self)
#define RB_TYPE_P(obj, type)
static VALUE string_to_r_strict(VALUE self)
static VALUE f_sub(VALUE x, VALUE y)
static VALUE f_odd_p(VALUE integer)
rb_funcall2(argv[0], id_yield, argc-1, argv+1)
#define MUL_OVERFLOW_LONG_P(a, b)
static VALUE nurat_mul(VALUE self, VALUE other)
static VALUE k_rational_p(VALUE x)
void rb_match_busy(VALUE)
RUBY_EXTERN VALUE rb_cNilClass
size_t strlen(const char *)
static VALUE f_addsub(VALUE self, VALUE anum, VALUE aden, VALUE bnum, VALUE bden, int k)
static int read_sign(const char **s)
const char * rb_obj_classname(VALUE)
static VALUE nurat_expt(VALUE self, VALUE other)
static VALUE nurat_floor(VALUE self)
static VALUE float_rationalize(int argc, VALUE *argv, VALUE self)
VALUE rb_gcd_normal(VALUE self, VALUE other)
#define rb_check_trusted(obj)
static VALUE f_negative_p(VALUE x)
#define RGENGC_WB_PROTECTED_RATIONAL
VALUE rb_rational_new(VALUE, VALUE)
static void nurat_int_check(VALUE num)
static VALUE nurat_s_alloc(VALUE klass)
static VALUE nurat_coerce(VALUE self, VALUE other)
rb_funcall(memo->yielder, id_lshift, 1, rb_assoc_new(memo->prev_value, memo->prev_elts))
SSL_METHOD *(* func)(void)
#define rb_usascii_str_new2
VALUE rb_gcd(VALUE self, VALUE other)
static VALUE nurat_s_new(int argc, VALUE *argv, VALUE klass)
static VALUE nurat_loader(VALUE self, VALUE a)
#define rb_check_frozen(obj)
static VALUE nurat_fdiv(VALUE self, VALUE other)
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
#define k_exact_zero_p(x)
static VALUE f_lt_p(VALUE x, VALUE y)
RUBY_EXTERN VALUE rb_cFloat
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
void rb_raise(VALUE exc, const char *fmt,...)
static VALUE k_numeric_p(VALUE x)
static VALUE float_denominator(VALUE self)
#define rb_rational_new1(x)
static VALUE f_one_p(VALUE x)
static VALUE integer_rationalize(int argc, VALUE *argv, VALUE self)
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
void rb_must_asciicompat(VALUE)
static VALUE nurat_floor_n(int argc, VALUE *argv, VALUE self)
VALUE rb_big_new(long len, int sign)
VALUE rb_lcm(VALUE x, VALUE y)
void rb_undef_method(VALUE klass, const char *name)
static VALUE nurat_s_canonicalize_internal(VALUE klass, VALUE num, VALUE den)
VALUE rb_ivar_get(VALUE, ID)
VALUE rb_str_concat(VALUE, VALUE)
static VALUE f_rational_new_no_reduce2(VALUE klass, VALUE x, VALUE y)
VALUE rb_flt_rationalize_with_prec(VALUE, VALUE)
void rb_copy_generic_ivar(VALUE, VALUE)
static VALUE nurat_marshal_load(VALUE self, VALUE a)
static VALUE numeric_numerator(VALUE self)
static VALUE nurat_truncate_n(int argc, VALUE *argv, VALUE self)
VALUE rb_rational_raw(VALUE, VALUE)
VALUE rb_cstr_to_rat(const char *, int)
static VALUE f_add(VALUE x, VALUE y)
static long i_gcd(long x, long y)
#define rb_raise_zerodiv()
static VALUE nurat_ceil(VALUE self)
static VALUE f_to_i(VALUE x)
static VALUE integer_numerator(VALUE self)
static VALUE k_integer_p(VALUE x)
static VALUE f_round_common(int argc, VALUE *argv, VALUE self, VALUE(*func)(VALUE))
VALUE rb_dbl2big(double d)
VALUE rb_Rational(VALUE, VALUE)
void nurat_canonicalization(int)
#define StringValuePtr(v)
static VALUE f_imul(long a, long b)
VALUE rb_str_to_inum(VALUE str, int base, int badcheck)
static int read_den(const char **s, int strict, VALUE *num)
RUBY_EXTERN VALUE rb_cRational
static void Tcl_Interp * ip
#define RARRAY_AREF(a, i)
VALUE rb_str_cat2(VALUE, const char *)
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
static VALUE nurat_dumper(VALUE self)
void rb_backref_set(VALUE)
static int read_digits(const char **s, int strict, VALUE *num, int *count)
VALUE rb_gcdlcm(VALUE self, VALUE other)
static VALUE nurat_to_s(VALUE self)
static int parse_rat(const char *s, int strict, VALUE *num)
static VALUE nurat_s_convert(int argc, VALUE *argv, VALUE klass)
VALUE rb_call_super(int, const VALUE *)
double rb_str_to_dbl(VALUE, int)
static VALUE nurat_int_value(VALUE num)
#define RUBY_FUNC_EXPORTED
static int isdecimal(int c)
VALUE rb_num_coerce_cmp(VALUE, VALUE, ID)
static VALUE nurat_eqeq_p(VALUE self, VALUE other)
static VALUE nurat_sub(VALUE self, VALUE other)
#define RBIGNUM_DIGITS(b)
static int read_rat_nos(const char **s, int sign, int strict, VALUE *num)
VALUE rb_rational_reciprocal(VALUE x)
static VALUE nurat_cmp(VALUE self, VALUE other)
RUBY_EXTERN VALUE rb_cInteger
static VALUE f_kind_of_p(VALUE x, VALUE c)
VALUE rb_flt_rationalize(VALUE)
static void float_decode_internal(VALUE self, VALUE *rf, VALUE *rn)
#define rb_rational_raw1(x)
static VALUE f_minus_one_p(VALUE x)
static VALUE float_numerator(VALUE self)
static VALUE nilclass_to_r(VALUE self)
static void skip_ws(const char **s)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
VALUE rb_assoc_new(VALUE car, VALUE cdr)
static VALUE f_lcm(VALUE x, VALUE y)
static VALUE nurat_truncate(VALUE self)
static VALUE string_to_r(VALUE self)
VALUE rb_big_mul(VALUE x, VALUE y)
static VALUE f_rational_new_bang1(VALUE klass, VALUE x)
static VALUE nurat_div(VALUE self, VALUE other)
VALUE rb_Complex(VALUE x, VALUE y)
static VALUE nurat_round_n(int argc, VALUE *argv, VALUE self)
RUBY_EXTERN int isinf(double)
static int read_rat(const char **s, int strict, VALUE *num)
static VALUE nurat_to_r(VALUE self)
RUBY_EXTERN VALUE rb_cString
void rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE(*dumper)(VALUE), VALUE(*loader)(VALUE, VALUE))
static VALUE numeric_quo(VALUE x, VALUE y)
static VALUE integer_denominator(VALUE self)
static VALUE f_cmp(VALUE x, VALUE y)
static VALUE nurat_f_rational(int argc, VALUE *argv, VALUE klass)
static VALUE f_to_f(VALUE x)
static VALUE nurat_s_canonicalize_internal_no_reduce(VALUE klass, VALUE num, VALUE den)
void rb_str_modify(VALUE)
#define NEWOBJ_OF(obj, type, klass, flags)
static VALUE nurat_to_f(VALUE self)
static int islettere(int c)
#define RRATIONAL_SET_NUM(rat, n)
static VALUE f_muldiv(VALUE self, VALUE anum, VALUE aden, VALUE bnum, VALUE bden, int k)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
static int read_num(const char **s, int numsign, int strict, VALUE *num)
st_index_t rb_memhash(const void *ptr, long len)
static VALUE f_format(VALUE self, VALUE(*func)(VALUE))
static VALUE nurat_ceil_n(int argc, VALUE *argv, VALUE self)
RUBY_EXTERN VALUE rb_cObject
VALUE rb_big_norm(VALUE x)
static VALUE nilclass_rationalize(int argc, VALUE *argv, VALUE self)
static VALUE f_div(VALUE x, VALUE y)
static VALUE f_mul(VALUE x, VALUE y)
static VALUE nurat_add(VALUE self, VALUE other)
VALUE rb_backref_get(void)
static VALUE nurat_round(VALUE self)
VALUE rb_int2big(SIGNED_VALUE n)
rb_ivar_set(yielder, id_memo, LONG2NUM(++count))
static VALUE nurat_denominator(VALUE self)
static VALUE nurat_numerator(VALUE self)
#define RRATIONAL_SET_DEN(rat, d)
#define assert(condition)
static VALUE nurat_marshal_dump(VALUE self)
static void nurat_rationalize_internal(VALUE a, VALUE b, VALUE *p, VALUE *q)
static VALUE integer_to_r(VALUE self)
VALUE rb_cstr_to_inum(const char *str, int base, int badcheck)
static VALUE nurat_hash(VALUE self)
static VALUE f_zero_p(VALUE x)
static VALUE nurat_rationalize(int argc, VALUE *argv, VALUE self)
static VALUE float_to_r(VALUE self)
VALUE rb_num_coerce_bin(VALUE, VALUE, ID)
RUBY_EXTERN VALUE rb_eFloatDomainError
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
#define ALLOCV_N(type, v, n)
void rb_warn(const char *fmt,...)
static VALUE f_rational_new2(VALUE klass, VALUE x, VALUE y)
static VALUE f_gcd(VALUE x, VALUE y)
RUBY_EXTERN VALUE rb_cNumeric
VALUE rb_convert_type(VALUE, int, const char *, const char *)
static VALUE k_float_p(VALUE x)
static VALUE f_gcd_normal(VALUE x, VALUE y)
static VALUE nurat_inspect(VALUE self)
#define rb_rational_new2(x, y)
static VALUE nurat_s_new_internal(VALUE klass, VALUE num, VALUE den)
static VALUE f_eqeq_p(VALUE x, VALUE y)