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"));