inline static VALUE nurat_s_canonicalize_internal(VALUE klass, VALUE num, VALUE den) { VALUE gcd; switch (FIX2INT(f_cmp(den, ZERO))) { case -1: num = f_negate(num); den = f_negate(den); break; case 0: rb_raise_zerodiv(); break; } gcd = f_gcd(num, den); num = f_idiv(num, gcd); den = f_idiv(den, gcd); #ifdef CANON if (f_one_p(den) && canonicalization) return num; #endif return nurat_s_new_internal(klass, num, den); }
static VALUE nurat_s_new_bang(int argc, VALUE *argv, VALUE klass) { VALUE num, den; switch (rb_scan_args(argc, argv, "11", &num, &den)) { case 1: if (!k_integer_p(num)) num = f_to_i(num); den = ONE; break; default: if (!k_integer_p(num)) num = f_to_i(num); if (!k_integer_p(den)) den = f_to_i(den); switch (FIX2INT(f_cmp(den, ZERO))) { case -1: num = f_negate(num); den = f_negate(den); break; case 0: rb_raise_zerodiv(); break; } break; } return nurat_s_new_internal(klass, num, den); }
inline static VALUE f_rational_new_bang2(VALUE klass, VALUE x, VALUE y) { assert(f_positive_p(y)); assert(f_nonzero_p(y)); return nurat_s_new_internal(klass, x, y); }
inline static VALUE nurat_s_canonicalize_internal_no_reduce(VALUE klass, VALUE num, VALUE den) { switch (FIX2INT(f_cmp(den, ZERO))) { case -1: num = f_negate(num); den = f_negate(den); break; case 0: rb_raise(rb_eZeroDivError, "devided by zero"); break; } if (f_equal_p(den, ONE) && f_unify_p(klass)) return num; else return nurat_s_new_internal(klass, num, den); }
inline static VALUE nurat_s_canonicalize_internal(VALUE klass, VALUE num, VALUE den) { VALUE gcd; switch (FIX2INT(f_cmp(den, ZERO))) { case -1: num = f_negate(num); den = f_negate(den); break; case 0: rb_raise(rb_eZeroDivError, "devided by zero"); break; } gcd = f_gcd(num, den); num = f_idiv(num, gcd); den = f_idiv(den, gcd); if (f_one_p(den) && f_unify_p(klass)) return num; else return nurat_s_new_internal(klass, num, den); }
inline static VALUE f_rational_new_bang1(VALUE klass, VALUE x) { return nurat_s_new_internal(klass, x, ONE); }
static VALUE nurat_s_alloc(VALUE klass, SEL sel) { return nurat_s_new_internal(klass, ZERO, ONE); }
VALUE rb_rational_raw(VALUE x, VALUE y) { return nurat_s_new_internal(rb_cRational, x, y); }