20 #define ZERO INT2FIX(0)
21 #define ONE INT2FIX(1)
22 #define TWO INT2FIX(2)
30 #define f_boolcast(x) ((x) ? Qtrue : Qfalse)
34 f_##n(VALUE x, VALUE y)\
36 return rb_funcall(x, (op), 1, y);\
43 return rb_funcall(x, id_##n, 0);\
48 f_##n(VALUE x, VALUE y)\
50 return rb_funcall(x, id_##n, 1, y);\
171 #define f_expt10(x) f_expt(INT2FIX(10), x)
181 #define f_positive_p(x) (!f_negative_p(x))
201 #define f_nonzero_p(x) (!f_zero_p(x))
253 #define k_exact_p(x) (!k_float_p(x))
254 #define k_inexact_p(x) k_float_p(x)
256 #define k_exact_zero_p(x) (k_exact_p(x) && f_zero_p(x))
257 #define k_exact_one_p(x) (k_exact_p(x) && f_one_p(x))
260 #define f_gcd f_gcd_orig
322 VALUE r = f_gcd_orig(x, y);
339 #define get_dat1(x) \
340 struct RRational *dat;\
341 dat = ((struct RRational *)(x))
343 #define get_dat2(x,y) \
344 struct RRational *adat, *bdat;\
345 adat = ((struct RRational *)(x));\
346 bdat = ((struct RRational *)(y))
366 #define rb_raise_zerodiv() rb_raise(rb_eZeroDivError, "divided by 0")
416 #ifdef CANONICALIZATION_FOR_MATHN
421 static int canonicalization = 0;
426 canonicalization = f;
467 gcd =
f_gcd(num, den);
472 if (
f_one_p(den) && canonicalization)
492 if (
f_one_p(den) && canonicalization)
601 #define f_imul f_imul_orig
610 if (a == 0 || b == 0)
619 if (
NUM2LONG(r) != c || (c / a) != b)
630 VALUE r = f_imul_orig(x, y);
647 long ig =
i_gcd(ad, bd);
702 switch (
TYPE(other)) {
719 adat->num, adat->den,
720 bdat->num, bdat->den,
'+');
744 switch (
TYPE(other)) {
761 adat->num, adat->den,
762 bdat->num, bdat->den,
'-');
792 long g1 =
i_gcd(an, bd);
793 long g2 =
i_gcd(ad, bn);
795 num =
f_imul(an / g1, bn / g2);
796 den =
f_imul(ad / g2, bd / g1);
825 switch (
TYPE(other)) {
842 adat->num, adat->den,
843 bdat->num, bdat->den,
'*');
868 switch (
TYPE(other)) {
887 if (x != 0.0 && modf(x, &den) == 0.0) {
900 bdat->den, bdat->num);
903 adat->num, adat->den,
904 bdat->num, bdat->den,
'/');
959 switch (
TYPE(other)) {
968 num =
f_expt(dat->num, other);
969 den =
f_expt(dat->den, other);
983 rb_warn(
"in a**b, b may be too big");
1010 switch (
TYPE(other)) {
1017 return f_cmp(dat->num, other);
1034 num1 =
f_mul(adat->num, bdat->den);
1035 num2 =
f_mul(bdat->num, adat->den);
1061 switch (
TYPE(other)) {
1099 switch (
TYPE(other)) {
1125 return f_idiv(
self, other);
1147 nurat_true(
VALUE self)
1157 return f_idiv(dat->num, dat->den);
1190 return f_idiv(dat->num, dat->den);
1223 return (*
func)(
self);
1365 return f_fdiv(dat->num, dat->den);
1385 #define id_ceil rb_intern("ceil")
1386 #define f_ceil(x) rb_funcall((x), id_ceil, 0)
1388 #define id_quo rb_intern("quo")
1389 #define f_quo(x,y) rb_funcall((x), id_quo, 1, (y))
1391 #define f_reciprocal(x) f_quo(ONE, (x))
1455 VALUE c, k, t, p0, p1, p2, q0, q1, q2;
1542 s = (*func)(dat->num);
1647 return f_gcd(
self, other);
1667 return f_lcm(
self, other);
1712 #define id_numerator rb_intern("numerator")
1713 #define f_numerator(x) rb_funcall((x), id_numerator, 0)
1715 #define id_denominator rb_intern("denominator")
1716 #define f_denominator(x) rb_funcall((x), id_denominator, 0)
1718 #define id_to_r rb_intern("to_r")
1719 #define f_to_r(x) rb_funcall((x), id_to_r, 0)
1880 float_decode(
VALUE self)
1889 #define id_lshift rb_intern("<<")
1890 #define f_lshift(x,n) rb_funcall((x), id_lshift, 1, (n))
1991 #define DIGITS "(?:[0-9](?:_[0-9]|[0-9])*)"
1992 #define NUMERATOR "(?:" DIGITS "?\\.)?" DIGITS "(?:[eE][-+]?" DIGITS ")?"
1993 #define DENOMINATOR DIGITS
1994 #define PATTERN "\\A" WS "([-+])?(" NUMERATOR ")(?:\\/(" DENOMINATOR "))?" WS
1999 static const char rat_pat_source[] =
PATTERN;
2000 static const char an_e_pat_source[] =
"[eE]";
2001 static const char a_dot_pat_source[] =
"\\.";
2002 static const char underscores_pat_source[] =
"_+";
2004 if (rat_pat)
return;
2006 rat_pat =
rb_reg_new(rat_pat_source,
sizeof rat_pat_source - 1, 0);
2009 an_e_pat =
rb_reg_new(an_e_pat_source,
sizeof an_e_pat_source - 1, 0);
2012 a_dot_pat =
rb_reg_new(a_dot_pat_source,
sizeof a_dot_pat_source - 1, 0);
2015 underscores_pat =
rb_reg_new(underscores_pat_source,
2016 sizeof underscores_pat_source - 1, 0);
2023 #define id_match rb_intern("match")
2024 #define f_match(x,y) rb_funcall((x), id_match, 1, (y))
2026 #define id_split rb_intern("split")
2027 #define f_split(x,y) rb_funcall((x), id_split, 1, (y))
2044 VALUE v, ifp, exp, ip, fp;
2125 #define id_gsub rb_intern("gsub")
2126 #define f_gsub(x,y,z) rb_funcall((x), id_gsub, 2, (y), (z))
2154 VALUE s, a, a1, backref;
2159 s =
f_gsub(
self, underscores_pat, an_underscore);
2173 #define id_to_r rb_intern("to_r")
2174 #define f_to_r(x) rb_funcall((x), id_to_r, 0)
2179 VALUE a1, a2, backref;
2239 (!f_integer_p(a1) || !f_integer_p(a2)))
2240 return f_div(a1, a2);
2295 #define rb_intern(str) rb_intern_const(str)
2297 assert(fprintf(stderr,
"assert() is now active\n"));
RUBY_EXTERN VALUE rb_cString
static VALUE numeric_denominator(VALUE self)
#define RSTRING_LEN(string)
static long NUM2LONG(VALUE x)
static VALUE string_to_r_strict(VALUE self)
static VALUE f_sub(VALUE x, VALUE y)
#define rb_rational_new2(x, y)
RUBY_EXTERN VALUE rb_cFloat
VALUE rb_num_coerce_bin(VALUE, VALUE, ID)
static VALUE nurat_mul(VALUE self, VALUE other)
static VALUE k_rational_p(VALUE x)
static VALUE f_rational_new_no_reduce1(VALUE klass, VALUE x)
void rb_backref_set(VALUE)
static VALUE f_addsub(VALUE self, VALUE anum, VALUE aden, VALUE bnum, VALUE bden, int k)
static VALUE nurat_expt(VALUE self, VALUE other)
VALUE rb_lcm(VALUE self, VALUE other)
static VALUE nurat_floor(VALUE self)
static VALUE float_rationalize(int argc, VALUE *argv, VALUE self)
static void nurat_int_check(VALUE num)
static VALUE nurat_s_alloc(VALUE klass)
static VALUE nurat_coerce(VALUE self, VALUE other)
VALUE rb_gcd(VALUE self, VALUE other)
static VALUE nurat_s_new(int argc, VALUE *argv, VALUE klass)
#define RFLOAT_VALUE(val)
static VALUE nurat_fdiv(VALUE self, VALUE other)
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
#define k_exact_zero_p(x)
VALUE rb_str_concat(VALUE, VALUE)
st_index_t rb_memhash(const void *ptr, long len)
static VALUE f_lt_p(VALUE x, VALUE y)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
#define RSTRING_PTR(string)
VALUE rb_backref_get(void)
void rb_raise(VALUE exc, const char *fmt,...)
static VALUE k_numeric_p(VALUE x)
VALUE rb_convert_type(VALUE, int, const char *, const char *)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
static VALUE float_denominator(VALUE self)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
static VALUE f_one_p(VALUE x)
#define RARRAY_LEN(ARRAY)
static VALUE string_to_r_internal(VALUE self)
static VALUE integer_rationalize(int argc, VALUE *argv, VALUE self)
double rb_str_to_dbl(VALUE, int)
VALUE rb_reg_match_post(VALUE)
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
static VALUE nurat_floor_n(int argc, VALUE *argv, VALUE self)
static VALUE f_negative_p(VALUE x)
void rb_undef_method(VALUE klass, const char *name)
static VALUE nurat_s_canonicalize_internal(VALUE klass, VALUE num, VALUE den)
static VALUE f_rational_new_no_reduce2(VALUE klass, VALUE x, VALUE y)
const char * rb_obj_classname(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)
static VALUE f_add(VALUE x, VALUE y)
VALUE rb_rational_raw(VALUE x, VALUE y)
static long i_gcd(long x, long y)
#define rb_raise_zerodiv()
static VALUE nurat_ceil(VALUE self)
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)
void nurat_canonicalization(int)
static VALUE f_imul(long a, long b)
VALUE rb_str_to_inum(VALUE str, int base, int badcheck)
VALUE rb_str_cat2(VALUE, const char *)
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
#define NEWOBJ(obj, type)
VALUE rb_gcdlcm(VALUE self, VALUE other)
static VALUE nurat_to_s(VALUE self)
static VALUE nurat_s_convert(int argc, VALUE *argv, VALUE klass)
static VALUE nurat_int_value(VALUE num)
void rb_gc_register_mark_object(VALUE obj)
#define RUBY_FUNC_EXPORTED
RUBY_EXTERN int isinf(double)
static VALUE nurat_eqeq_p(VALUE self, VALUE other)
static VALUE nurat_sub(VALUE self, VALUE other)
#define rb_rational_new1(x)
static VALUE an_underscore
static VALUE nurat_cmp(VALUE self, VALUE other)
static VALUE f_kind_of_p(VALUE x, VALUE c)
VALUE rb_reg_new(const char *, long, int)
SSL_METHOD *(* func)(void)
static void float_decode_internal(VALUE self, VALUE *rf, VALUE *rn)
VALUE rb_funcall2(VALUE, ID, int, const VALUE *)
Calls a method.
static VALUE float_numerator(VALUE self)
static VALUE nilclass_to_r(VALUE self)
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)
#define rb_rational_raw2(x, y)
char * strchr(char *, char)
RUBY_EXTERN VALUE rb_cInteger
static void make_patterns(void)
void rb_match_busy(VALUE)
VALUE rb_call_super(int, const VALUE *)
#define RARRAY_PTR(ARRAY)
VALUE rb_Complex(VALUE x, VALUE y)
static VALUE nurat_round_n(int argc, VALUE *argv, VALUE self)
RUBY_EXTERN VALUE rb_cNumeric
static VALUE nurat_to_r(VALUE self)
static VALUE f_gt_p(VALUE x, VALUE y)
static VALUE f_rational_new1(VALUE klass, VALUE x)
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)
VALUE rb_usascii_str_new2(const char *)
static VALUE nurat_to_f(VALUE self)
static VALUE f_muldiv(VALUE self, VALUE anum, VALUE aden, VALUE bnum, VALUE bden, int k)
static VALUE f_rational_new_bang2(VALUE klass, VALUE x, VALUE y)
VALUE rb_rational_new(VALUE x, VALUE y)
static VALUE f_format(VALUE self, VALUE(*func)(VALUE))
static VALUE nurat_ceil_n(int argc, VALUE *argv, VALUE self)
static VALUE nilclass_rationalize(int argc, VALUE *argv, VALUE self)
static VALUE f_div(VALUE x, VALUE y)
static VALUE f_eqeq_p(VALUE x, VALUE y)
VALUE rb_Rational(VALUE x, VALUE y)
static VALUE nurat_add(VALUE self, VALUE other)
static VALUE nurat_round(VALUE self)
VALUE rb_int2big(SIGNED_VALUE n)
static VALUE nurat_denominator(VALUE self)
static VALUE nurat_numerator(VALUE self)
#define assert(condition)
static VALUE nurat_marshal_dump(VALUE self)
#define StringValuePtr(v)
RUBY_EXTERN VALUE rb_eFloatDomainError
static void nurat_rationalize_internal(VALUE a, VALUE b, VALUE *p, VALUE *q)
void rb_copy_generic_ivar(VALUE, VALUE)
static VALUE integer_to_r(VALUE self)
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)
#define OBJSETUP(obj, c, t)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
void rb_warn(const char *fmt,...)
RUBY_EXTERN VALUE rb_cNilClass
static VALUE f_rational_new2(VALUE klass, VALUE x, VALUE y)
static VALUE f_gcd(VALUE x, VALUE y)
static VALUE k_float_p(VALUE x)
VALUE rb_reg_nth_match(int, VALUE)
static VALUE nurat_inspect(VALUE self)
VALUE rb_rational_reciprocal(VALUE x)
static VALUE nurat_s_new_internal(VALUE klass, VALUE num, VALUE den)
VALUE rb_num_coerce_cmp(VALUE, VALUE, ID)
static VALUE underscores_pat