static mrb_value num_div(mrb_state *mrb, mrb_value x) { mrb_value y; mrb_float f; f = mrb_to_flo(mrb, x); mrb_get_args(mrb, "o", &y); #ifdef MRB_COMPLEX if (mrb_complex_p(y)) { if (fabs(mrb_real(y)) > fabs(mrb_imag(y))) { mrb_float r, n; r = mrb_imag(y) / mrb_real(y); n = mrb_real(y) * (r*r+1); return mrb_complex_value(mrb, f/n, -f*r/n); } else { mrb_float r, n; r = mrb_real(y) / mrb_imag(y); n = mrb_imag(y) * (r*r+1); return mrb_complex_value(mrb, f*r/n, -f/n); } } #endif return mrb_float_value(mrb, f / mrb_to_flo(mrb, y)); }
mrb_value mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y) { #ifdef MRB_WITHOUT_FLOAT if (!mrb_fixnum_p(y)) { mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); } return mrb_fixnum_value(mrb_fixnum(x) / mrb_fixnum(y)); #else return mrb_float_value(mrb, mrb_to_flo(mrb, x) / mrb_to_flo(mrb, y)); #endif }
/* * call-seq: * * num ** other -> num * * Raises <code>num</code> the <code>other</code> power. * * 2.0**3 #=> 8.0 */ static mrb_value num_pow(mrb_state *mrb, mrb_value x) { mrb_value y; mrb_float d; mrb_get_args(mrb, "o", &y); d = pow(mrb_to_flo(mrb, x), mrb_to_flo(mrb, y)); if (mrb_fixnum_p(x) && mrb_fixnum_p(y) && FIXABLE(d)) return mrb_fixnum_value((mrb_int)d); return mrb_float_value(mrb, d); }
/* * call-seq: * * num ** other -> num * * Raises <code>num</code> the <code>other</code> power. * * 2.0**3 #=> 8.0 */ static mrb_value num_pow(mrb_state *mrb, mrb_value x) { mrb_value y; int both_int = FALSE; mrb_float d; mrb_get_args(mrb, "o", &y); if (mrb_fixnum_p(x) && mrb_fixnum_p(y)) both_int = TRUE; d = pow(mrb_to_flo(mrb, x), mrb_to_flo(mrb, y)); if (both_int && FIXABLE(d)) return mrb_fixnum_value((mrb_int)d); return mrb_float_value(d); }
/* * call-seq: * self.f <=> other.f => -1, 0, +1 * < => -1 * = => 0 * > => +1 * Comparison---Returns -1, 0, or +1 depending on whether <i>fix</i> is * less than, equal to, or greater than <i>numeric</i>. This is the * basis for the tests in <code>Comparable</code>. */ static mrb_value num_cmp(mrb_state *mrb, mrb_value self) { mrb_value other; mrb_float x, y; mrb_get_args(mrb, "o", &other); x = mrb_to_flo(mrb, self); switch (mrb_type(other)) { case MRB_TT_FIXNUM: y = (mrb_float)mrb_fixnum(other); break; case MRB_TT_FLOAT: y = mrb_float(other); break; default: return mrb_nil_value(); } if (x > y) return mrb_fixnum_value(1); else { if (x < y) return mrb_fixnum_value(-1); return mrb_fixnum_value(0); } }
/* * call-seq: * fix.divmod(numeric) -> array * * See <code>Numeric#divmod</code>. */ static mrb_value fix_divmod(mrb_state *mrb, mrb_value x) { mrb_value y; mrb_get_args(mrb, "o", &y); if (mrb_fixnum_p(y)) { mrb_int div, mod; if (mrb_fixnum(y) == 0) { return mrb_assoc_new(mrb, mrb_float_value(mrb, INFINITY), mrb_float_value(mrb, NAN)); } fixdivmod(mrb, mrb_fixnum(x), mrb_fixnum(y), &div, &mod); return mrb_assoc_new(mrb, mrb_fixnum_value(div), mrb_fixnum_value(mod)); } else { mrb_float div, mod; mrb_value a, b; flodivmod(mrb, (mrb_float)mrb_fixnum(x), mrb_to_flo(mrb, y), &div, &mod); a = mrb_float_value(mrb, (mrb_int)div); b = mrb_float_value(mrb, mod); return mrb_assoc_new(mrb, a, b); } }
static mrb_value num_abs(mrb_state *mrb, mrb_value num) { if (mrb_to_flo(mrb, num) < 0) { return num_uminus(mrb, num); } return num; }
static mrb_value flo_mul(mrb_state *mrb, mrb_value x) { mrb_value y; mrb_get_args(mrb, "o", &y); return mrb_float_value(mrb, mrb_float(x) * mrb_to_flo(mrb, y)); }
static mrb_value num_div(mrb_state *mrb, mrb_value x) { mrb_float y; mrb_get_args(mrb, "f", &y); return mrb_float_value(mrb, mrb_to_flo(mrb, x) / y); }
static mrb_value flo_mod(mrb_state *mrb, mrb_value x) { mrb_value y; mrb_float mod; mrb_get_args(mrb, "o", &y); flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), 0, &mod); return mrb_float_value(mrb, mod); }
static mrb_value flo_minus(mrb_state *mrb, mrb_value x) { mrb_value y; mrb_get_args(mrb, "o", &y); #ifdef MRB_COMPLEX if (mrb_complex_p(y)) { return mrb_complex_value(mrb, mrb_float(x) - mrb_real(y), mrb_imag(y)); } #endif return mrb_float_value(mrb, mrb_float(x) - mrb_to_flo(mrb, y)); }
static mrb_value flo_divmod(mrb_state *mrb, mrb_value x) { mrb_value y; mrb_float div, mod; mrb_value a, b; mrb_get_args(mrb, "o", &y); flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), &div, &mod); a = mrb_float_value(mrb, (mrb_int)div); b = mrb_float_value(mrb, mod); return mrb_assoc_new(mrb, a, b); }
mrb_value mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y) { mrb_int a; a = mrb_fixnum(x); if (mrb_fixnum_p(y)) { mrb_int b, c; b = mrb_fixnum(y); if (mrb_int_sub_overflow(a, b, &c)) { return mrb_float_value(mrb, (mrb_float)a - (mrb_float)b); } return mrb_fixnum_value(c); } return mrb_float_value(mrb, (mrb_float)a - mrb_to_flo(mrb, y)); }
mrb_value mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y) { mrb_int a; a = mrb_fixnum(x); if (mrb_fixnum_p(y)) { mrb_int b, c; if (a == 0) return y; b = mrb_fixnum(y); if (mrb_int_add_overflow(a, b, &c)) { return mrb_float_value(mrb, (mrb_float)a + (mrb_float)b); } return mrb_fixnum_value(c); } return mrb_float_value(mrb, (mrb_float)a + mrb_to_flo(mrb, y)); }
static mrb_value num_div(mrb_state *mrb, mrb_value x) { #ifdef MRB_WITHOUT_FLOAT mrb_value y; mrb_get_args(mrb, "o", &y); if (!mrb_fixnum_p(y)) { mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); } return mrb_fixnum_value(mrb_fixnum(x) / mrb_fixnum(y)); #else mrb_float y; mrb_get_args(mrb, "f", &y); return mrb_float_value(mrb, mrb_to_flo(mrb, x) / y); #endif }
mrb_value mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y) { mrb_int a; a = mrb_fixnum(x); if (mrb_fixnum_p(y)) { mrb_int b, c; b = mrb_fixnum(y); c = a - b; if (((a < 0) ^ (b < 0)) != 0 && (a < 0) != (c < 0)) { /* integer overflow */ return mrb_float_value((mrb_float)a - (mrb_float)b); } return mrb_fixnum_value(c); } return mrb_float_value((mrb_float)a - mrb_to_flo(mrb, y)); }
mrb_value mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y) { mrb_int a; a = mrb_fixnum(x); if (a == 0) return y; if (mrb_fixnum_p(y)) { mrb_int b, c; b = mrb_fixnum(y); c = a + b; if (((a < 0) ^ (b < 0)) == 0 && (a < 0) != (c < 0)) { /* integer overflow */ return mrb_float_value((mrb_float)a + (mrb_float)b); } return mrb_fixnum_value(c); } return mrb_float_value((mrb_float)a + mrb_to_flo(mrb, y)); }
mrb_value mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y) { mrb_int a; a = mrb_fixnum(x); if (a == 0) return x; if (mrb_fixnum_p(y)) { mrb_int b, c; b = mrb_fixnum(y); if (FIT_SQRT_INT(a) && FIT_SQRT_INT(b)) return mrb_fixnum_value(a*b); c = a * b; if (a != 0 && c/a != b) { return mrb_float_value((mrb_float)a*(mrb_float)b); } return mrb_fixnum_value(c);; } return mrb_float_value((mrb_float)a * mrb_to_flo(mrb, y)); }
mrb_value mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y) { mrb_int a; a = mrb_fixnum(x); if (mrb_fixnum_p(y)) { mrb_int b, c; if (a == 0) return x; b = mrb_fixnum(y); if (mrb_int_mul_overflow(a, b, &c)) { #ifndef MRB_WITHOUT_FLOAT return mrb_float_value(mrb, (mrb_float)a * (mrb_float)b); #endif } return mrb_fixnum_value(c); } #ifdef MRB_WITHOUT_FLOAT mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); #else return mrb_float_value(mrb, (mrb_float)a * mrb_to_flo(mrb, y)); #endif }
static mrb_value fix_mod(mrb_state *mrb, mrb_value x) { mrb_value y; mrb_int a; mrb_get_args(mrb, "o", &y); a = mrb_fixnum(x); if (mrb_fixnum_p(y)) { mrb_int b, mod; if ((b=mrb_fixnum(y)) == 0) { return mrb_float_value(mrb, NAN); } fixdivmod(mrb, a, b, 0, &mod); return mrb_fixnum_value(mod); } else { mrb_float mod; flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), 0, &mod); return mrb_float_value(mrb, mod); } }
static mrb_value fix_mod(mrb_state *mrb, mrb_value x) { mrb_value y; mrb_int a, b; mrb_get_args(mrb, "o", &y); a = mrb_fixnum(x); if (mrb_fixnum_p(y) && (b=mrb_fixnum(y)) != 0) { mrb_int mod; if (mrb_fixnum(y) == 0) { return mrb_float_value(str_to_mrb_float("nan")); } fixdivmod(mrb, a, mrb_fixnum(y), 0, &mod); return mrb_fixnum_value(mod); } else { mrb_float mod; flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), 0, &mod); return mrb_float_value(mod); } }
static mrb_value num_uminus(mrb_state *mrb, mrb_value num) { return mrb_float_value((mrb_float)0 - mrb_to_flo(mrb, num)); }
MRB_API mrb_value mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y) { return mrb_float_value(mrb, mrb_to_flo(mrb, x) / mrb_to_flo(mrb, y)); }
/* ZeroDivisionError */ return mrb_fixnum_value(0); #else return mrb_float_value(mrb, NAN); #endif } fixdivmod(mrb, a, b, 0, &mod); return mrb_fixnum_value(mod); } #ifdef MRB_WITHOUT_FLOAT mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); #else else { mrb_float mod; flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), 0, &mod); return mrb_float_value(mrb, mod); } #endif } /* * call-seq: * fix.divmod(numeric) -> array * * See <code>Numeric#divmod</code>. */ static mrb_value fix_divmod(mrb_state *mrb, mrb_value x) { mrb_value y;