19 #if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H) 24 #define ZERO INT2FIX(0) 25 #define ONE INT2FIX(1) 26 #define TWO INT2FIX(2) 28 #define GMP_GCD_DIGITS 1 30 #define INT_POSITIVE_P(x) (FIXNUM_P(x) ? FIXNUM_POSITIVE_P(x) : BIGNUM_POSITIVE_P(x)) 31 #define INT_ZERO_P(x) (FIXNUM_P(x) ? FIXNUM_ZERO_P(x) : rb_bigzero_p(x)) 38 #define f_boolcast(x) ((x) ? Qtrue : Qfalse) 39 #define f_inspect rb_inspect 40 #define f_to_s rb_obj_as_string 44 f_##n(VALUE x, VALUE y)\ 46 return rb_funcall(x, (op), 1, y);\ 53 return rb_funcall(x, id_##n, 0);\ 58 f_##n(VALUE x, VALUE y)\ 60 return rb_funcall(x, id_##n, 1, y);\ 159 #define f_expt10(x) rb_int_pow(INT2FIX(10), x) 175 #define f_nonzero_p(x) (!f_zero_p(x)) 240 #define k_exact_p(x) (!k_float_p(x)) 241 #define k_inexact_p(x) k_float_p(x) 243 #define k_exact_zero_p(x) (k_exact_p(x) && f_zero_p(x)) 244 #define k_exact_one_p(x) (k_exact_p(x) && f_one_p(x)) 278 #define f_gcd f_gcd_orig 348 return rb_gcd_gmp(x, y);
360 VALUE r = f_gcd_orig(x, y);
377 #define get_dat1(x) \ 378 struct RRational *dat = RRATIONAL(x) 380 #define get_dat2(x,y) \ 381 struct RRational *adat = RRATIONAL(x), *bdat = RRATIONAL(y) 383 #define RRATIONAL_SET_NUM(rat, n) RB_OBJ_WRITE((rat), &((struct RRational *)(rat))->num,(n)) 384 #define RRATIONAL_SET_DEN(rat, d) RB_OBJ_WRITE((rat), &((struct RRational *)(rat))->den,(d)) 441 #ifdef CANONICALIZATION_FOR_MATHN 451 canonicalization =
f;
493 gcd =
f_gcd(num, den);
498 if (
f_one_p(den) && canonicalization)
510 if (
f_one_p(den) && canonicalization)
638 #define f_imul f_imul_orig 646 if (a == 0 || b == 0)
666 VALUE r = f_imul_orig(x, y);
683 long ig =
i_gcd(ad, bd);
754 adat->num, adat->den,
755 bdat->num, bdat->den,
'+');
795 adat->num, adat->den,
796 bdat->num, bdat->den,
'-');
833 long g1 =
i_gcd(an, bd);
834 long g2 =
i_gcd(ad, bn);
836 num =
f_imul(an / g1, bn / g2);
837 den =
f_imul(ad / g2, bd / g1);
881 adat->num, adat->den,
882 bdat->num, bdat->den,
'*');
927 bdat->den, bdat->num);
930 adat->num, adat->den,
931 bdat->num, bdat->den,
'/');
1054 rb_warn(
"in a**b, b may be too big");
1089 goto other_is_rational;
1199 return f_idiv(
self, other);
1221 nurat_true(
VALUE self)
1397 return (*
func)(
self);
1568 #define id_ceil rb_intern("ceil") 1569 #define f_ceil(x) rb_funcall((x), id_ceil, 0) 1571 #define id_quo rb_intern("quo") 1572 #define f_quo(x,y) rb_funcall((x), id_quo, 1, (y)) 1574 #define f_reciprocal(x) f_quo(ONE, (x)) 1638 VALUE c, k, t, p0, p1, p2, q0, q1, q2;
1681 VALUE e, a, b, p, q;
1723 s = (*func)(dat->num);
1853 return f_gcd(
self, other);
1871 return f_lcm(
self, other);
1924 #define id_numerator rb_intern("numerator") 1925 #define f_numerator(x) rb_funcall((x), id_numerator, 0) 1927 #define id_denominator rb_intern("denominator") 1928 #define f_denominator(x) rb_funcall((x), id_denominator, 0) 1930 #define id_to_r rb_intern("to_r") 1931 #define f_to_r(x) rb_funcall((x), id_to_r, 0) 1974 if (canonicalization) {
2128 float_decode(
VALUE self)
2181 VALUE e, a, b, p, q;
2205 VALUE two_times_f, den;
2215 VALUE radix_times_f, den;
2270 return (c ==
'-' || c ==
'+');
2288 return isdigit((
unsigned char)c);
2296 int us = 1, ret = 1;
2327 }
while (**s ==
'_');
2338 return (c ==
'e' || c ==
'E');
2365 if (canonicalization) {
2391 if (numsign ==
'-') {
2426 if (!
read_num(s, sign, strict, num))
2459 while (isspace((
unsigned char)**s))
2574 VALUE a1, a2, backref;
2621 (!f_integer_p(a1) || !f_integer_p(a2)))
2622 return f_div(a1, a2);
2679 #define rb_intern(str) rb_intern_const(str) 2681 assert(fprintf(stderr,
"assert() is now active\n"));
RUBY_EXTERN VALUE rb_cString
VALUE rb_int_plus(VALUE x, VALUE y)
static VALUE numeric_denominator(VALUE self)
VALUE rb_int_cmp(VALUE x, VALUE y)
static VALUE string_to_r_strict(VALUE self)
VALUE rb_rational_plus(VALUE self, VALUE other)
static VALUE f_sub(VALUE x, VALUE y)
static VALUE f_odd_p(VALUE integer)
VALUE rb_int_uminus(VALUE num)
#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)
size_t strlen(const char *)
static int f_one_p(VALUE x)
void rb_backref_set(VALUE)
static VALUE f_addsub(VALUE self, VALUE anum, VALUE aden, VALUE bnum, VALUE bden, int k)
static int read_sign(const char **s)
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 VALUE nurat_round_half_even(VALUE self)
#define RGENGC_WB_PROTECTED_RATIONAL
#define rb_usascii_str_new2
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)
static VALUE nurat_loader(VALUE self, VALUE a)
VALUE rb_int_equal(VALUE x, VALUE y)
static VALUE nurat_fdiv(VALUE self, VALUE other)
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
#define RRATIONAL_SET_NUM(rat, n)
void rb_must_asciicompat(VALUE)
VALUE rb_dbl_cmp(double a, double b)
SSL_METHOD *(* func)(void)
#define k_exact_zero_p(x)
VALUE rb_str_concat(VALUE, VALUE)
st_index_t rb_memhash(const void *ptr, long len)
static int k_rational_p(VALUE x)
VALUE rb_rational_uminus(VALUE self)
static int f_lt_p(VALUE x, VALUE y)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
VALUE rb_int_minus(VALUE x, VALUE y)
VALUE rb_backref_get(void)
VALUE rb_int_mul(VALUE x, VALUE y)
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 nurat_negative_p(VALUE self)
VALUE rb_ivar_get(VALUE, ID)
#define MUL_OVERFLOW_LONG_P(a, b)
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)
VALUE rb_int_divmod(VALUE x, VALUE y)
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.
static VALUE nurat_positive_p(VALUE self)
static VALUE nurat_floor_n(int argc, VALUE *argv, VALUE self)
double rb_int_fdiv_double(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)
static VALUE f_rational_new_no_reduce2(VALUE klass, VALUE x, VALUE y)
const char * rb_obj_classname(VALUE)
enum ruby_num_rounding_mode rb_num_get_rounding_option(VALUE opts)
static VALUE nurat_marshal_load(VALUE self, VALUE a)
#define NEWOBJ_OF(obj, type, klass, flags)
static VALUE numeric_numerator(VALUE self)
static VALUE nurat_truncate_n(int argc, VALUE *argv, VALUE self)
#define RB_TYPE_P(obj, type)
static VALUE f_add(VALUE x, VALUE y)
VALUE rb_rational_raw(VALUE x, VALUE y)
static long i_gcd(long x, long y)
VALUE rb_int_idiv(VALUE x, VALUE y)
static VALUE nurat_ceil(VALUE self)
static VALUE integer_numerator(VALUE self)
static VALUE f_round_common(int argc, VALUE *argv, VALUE self, VALUE(*func)(VALUE))
#define rb_rational_raw1(x)
VALUE rb_dbl2big(double d)
static void nurat_canonicalize(VALUE *num, VALUE *den)
void nurat_canonicalization(int)
RUBY_EXTERN VALUE rb_cObject
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)
VALUE rb_str_cat2(VALUE, const char *)
#define INT_NEGATIVE_P(x)
int rb_num_negative_p(VALUE)
void rb_check_trusted(VALUE obj)
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
static VALUE nurat_dumper(VALUE self)
static int read_digits(const char **s, int strict, VALUE *num, int *count)
VALUE rb_big_new(size_t len, int sign)
VALUE rb_int_and(VALUE x, VALUE y)
VALUE rb_gcdlcm(VALUE self, VALUE other)
static VALUE nurat_to_s(VALUE self)
VALUE rb_cstr_to_rat(const char *s, int strict)
#define ROUND_FUNC(mode, name)
static int parse_rat(const char *s, int strict, VALUE *num)
static VALUE nurat_s_convert(int argc, VALUE *argv, VALUE klass)
VALUE rb_int_lshift(VALUE x, VALUE y)
#define ALLOCV_N(type, v, n)
static VALUE nurat_int_value(VALUE num)
#define RUBY_FUNC_EXPORTED
RUBY_EXTERN int isinf(double)
static int isdecimal(int c)
static VALUE nurat_eqeq_p(VALUE self, VALUE other)
static VALUE nurat_sub(VALUE self, VALUE other)
void rb_num_zerodiv(void)
VALUE rb_int_abs(VALUE num)
static int read_rat_nos(const char **s, int sign, int strict, VALUE *num)
#define rb_rational_new1(x)
VALUE rb_int_modulo(VALUE x, VALUE y)
static void float_decode_internal(VALUE self, VALUE *rf, VALUE *rn)
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,...)
static int k_numeric_p(VALUE x)
static int k_integer_p(VALUE x)
VALUE rb_ivar_set(VALUE, ID, VALUE)
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)
RUBY_EXTERN VALUE rb_cInteger
VALUE rb_int_div(VALUE x, VALUE y)
void rb_match_busy(VALUE)
VALUE rb_Complex(VALUE x, VALUE y)
VALUE rb_rational_num(VALUE rat)
static VALUE nurat_round_n(int argc, VALUE *argv, VALUE self)
static int read_rat(const char **s, int strict, VALUE *num)
static double nurat_to_double(VALUE self)
static VALUE f_abs(VALUE x)
RUBY_EXTERN VALUE rb_cNumeric
static VALUE nurat_to_r(VALUE self)
static int f_kind_of_p(VALUE x, VALUE c)
#define RB_FLOAT_TYPE_P(obj)
static VALUE numeric_quo(VALUE x, VALUE y)
static VALUE integer_denominator(VALUE self)
static VALUE nurat_f_rational(int argc, VALUE *argv, VALUE klass)
void rb_str_modify(VALUE)
static VALUE nurat_s_canonicalize_internal_no_reduce(VALUE klass, VALUE num, VALUE den)
VALUE rb_equal(VALUE, VALUE)
static VALUE nurat_to_f(VALUE self)
static int islettere(int c)
static VALUE f_muldiv(VALUE self, VALUE anum, VALUE aden, VALUE bnum, VALUE bden, int k)
#define RARRAY_AREF(a, i)
VALUE rb_float_pow(VALUE x, VALUE y)
static int read_num(const char **s, int numsign, int strict, VALUE *num)
VALUE rb_rational_abs(VALUE self)
static VALUE nurat_round_half_down(VALUE self)
VALUE rb_rational_new(VALUE x, VALUE y)
#define FIXNUM_ZERO_P(num)
static VALUE f_format(VALUE self, VALUE(*func)(VALUE))
static VALUE nurat_ceil_n(int argc, VALUE *argv, VALUE self)
VALUE rb_big_norm(VALUE x)
void rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE(*dumper)(VALUE), VALUE(*loader)(VALUE, VALUE))
static VALUE nilclass_rationalize(int argc, VALUE *argv, VALUE self)
VALUE rb_rational_cmp(VALUE self, VALUE other)
static VALUE f_div(VALUE x, VALUE y)
VALUE rb_int_pow(VALUE x, VALUE y)
VALUE rb_Rational(VALUE x, VALUE y)
static VALUE f_mul(VALUE x, VALUE y)
VALUE rb_int2big(SIGNED_VALUE n)
static VALUE nurat_denominator(VALUE self)
static VALUE nurat_numerator(VALUE self)
static VALUE nurat_marshal_dump(VALUE self)
RUBY_EXTERN VALUE rb_eFloatDomainError
VALUE rb_rational_den(VALUE rat)
#define rb_check_frozen(obj)
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)
VALUE rb_cstr_to_inum(const char *str, int base, int badcheck)
static int f_zero_p(VALUE x)
static VALUE nurat_hash(VALUE self)
static int f_minus_one_p(VALUE x)
static VALUE nurat_rationalize(int argc, VALUE *argv, VALUE self)
#define RB_INTEGER_TYPE_P(obj)
static VALUE float_to_r(VALUE self)
static VALUE nurat_round_half_up(VALUE self)
#define RRATIONAL_SET_DEN(rat, d)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
void rb_provide(const char *)
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 f_gcd_normal(VALUE x, VALUE y)
static VALUE nurat_inspect(VALUE self)
VALUE rb_rational_reciprocal(VALUE x)
VALUE rb_flt_rationalize_with_prec(VALUE flt, VALUE prec)
static VALUE nurat_s_new_internal(VALUE klass, VALUE num, VALUE den)
static int k_float_p(VALUE x)
VALUE rb_num_coerce_cmp(VALUE, VALUE, ID)
#define INT_POSITIVE_P(x)
VALUE rb_gcd_normal(VALUE x, VALUE y)
VALUE rb_flt_rationalize(VALUE flt)
static VALUE f_eqeq_p(VALUE x, VALUE y)