/* * call-seq: * Math.log(numeric) -> float * Math.log(num,base) -> float * * Returns the natural logarithm of <i>numeric</i>. * If additional second argument is given, it will be the base * of logarithm. * * Math.log(1) #=> 0.0 * Math.log(Math::E) #=> 1.0 * Math.log(Math::E**3) #=> 3.0 * Math.log(12,3) #=> 2.2618595071429146 * */ static mrb_value math_log(mrb_state *mrb, mrb_value obj) { mrb_float x, base; int argc; argc = mrb_get_args(mrb, "f|f", &x, &base); x = log(x); if (argc == 2) { x /= log(base); } return mrb_float_value(x); }
/* * call-seq: * Math.atanh(x) -> float * * Computes the inverse hyperbolic tangent of <i>x</i>. */ static mrb_value math_atanh(mrb_state *mrb, mrb_value obj) { mrb_float x; mrb_get_args(mrb, "f", &x); if (x < -1.0 || x > 1.0) { domain_error(mrb, "atanh"); } x = atanh(x); return mrb_float_value(mrb, x); }
/* Returns a Float with the time since the epoch in microseconds. */ static mrb_value mrb_time_usec(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); #ifdef MRB_INT16 if (tm->usec > MRB_INT_MAX || tm->usec < MRB_INT_MIN) { return mrb_float_value(mrb, (mrb_float)tm->usec); } #endif return mrb_fixnum_value((mrb_int)tm->usec); }
static mrb_value flo_truncate(mrb_state *mrb, mrb_value num) { mrb_float f = mrb_float(num); if (f > 0.0) f = floor(f); if (f < 0.0) f = ceil(f); if (!FIXABLE(f)) { return mrb_float_value(mrb, f); } return mrb_fixnum_value((mrb_int)f); }
/* * call-seq: * Math.log10(numeric) -> float * * Returns the base 10 logarithm of <i>numeric</i>. * * Math.log10(1) #=> 0.0 * Math.log10(10) #=> 1.0 * Math.log10(10**100) #=> 100.0 * */ static mrb_value math_log10(mrb_state *mrb, mrb_value obj) { mrb_float x; mrb_get_args(mrb, "f", &x); if (x < 0.0) { domain_error(mrb, "log10"); } x = log10(x); return mrb_float_value(mrb, x); }
static mrb_value mrb_file_mtime(mrb_state *mrb, mrb_value self) { mrb_value obj; struct stat st; int fd; obj = mrb_obj_value(mrb_class_get(mrb, "Time")); fd = (int)mrb_fixnum(mrb_io_fileno(mrb, self)); if (fstat(fd, &st) == -1) return mrb_false_value(); return mrb_funcall(mrb, obj, "at", 1, mrb_float_value(mrb, st.st_mtime)); }
/* * call-seq: * Math.sqrt(numeric) -> float * * Returns the square root of <i>numeric</i>. * */ static mrb_value math_sqrt(mrb_state *mrb, mrb_value obj) { mrb_float x; mrb_get_args(mrb, "f", &x); if (x < 0.0) { domain_error(mrb, "sqrt"); } x = sqrt(x); return mrb_float_value(mrb, x); }
static mrb_value mrb_random_mt_g_rand(mrb_state *mrb, mrb_value max) { mrb_value value; if (mrb_fixnum(max) == 0) { value = mrb_float_value(mrb, mt_g_rand_real()); } else { value = mrb_fixnum_value(mt_g_rand() % mrb_fixnum(max)); } return value; }
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_float c; mrb_int b; if (a == 0) return x; 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) || !FIXABLE(c)) { return mrb_float_value(mrb, (mrb_float)a*(mrb_float)b); } return mrb_fixnum_value((mrb_int)c); } return mrb_float_value(mrb, (mrb_float)a * mrb_to_flo(mrb, y)); }
/* * 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, yv; mrb_get_args(mrb, "o", &y); yv = mrb_to_flo(mrb, y); d = pow(mrb_to_flo(mrb, x), yv); if (mrb_fixnum_p(x) && mrb_fixnum_p(y) && FIXABLE(d) && yv > 0) return mrb_fixnum_value((mrb_int)d); return mrb_float_value(mrb, d); }
/* ------------------------------------------------------------------------*/ void mrb_mruby_math_gem_init(mrb_state* mrb) { struct RClass *mrb_math; mrb_math = mrb_define_module(mrb, "Math"); mrb_define_class_under(mrb, mrb_math, "DomainError", mrb->eStandardError_class); #ifdef M_PI mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(mrb, M_PI)); #else mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(mrb, atan(1.0)*4.0)); #endif #ifdef M_E mrb_define_const(mrb, mrb_math, "E", mrb_float_value(mrb, M_E)); #else mrb_define_const(mrb, mrb_math, "E", mrb_float_value(mrb, exp(1.0))); #endif #ifdef MRB_USE_FLOAT mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(mrb, 1e-5)); #else mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(mrb, 1e-12)); #endif mrb_define_module_function(mrb, mrb_math, "sin", math_sin, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "cos", math_cos, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "tan", math_tan, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "asin", math_asin, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "acos", math_acos, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "atan", math_atan, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "atan2", math_atan2, MRB_ARGS_REQ(2)); mrb_define_module_function(mrb, mrb_math, "sinh", math_sinh, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "cosh", math_cosh, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "tanh", math_tanh, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "asinh", math_asinh, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "acosh", math_acosh, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "atanh", math_atanh, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "exp", math_exp, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "log", math_log, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); mrb_define_module_function(mrb, mrb_math, "log2", math_log2, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "log10", math_log10, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "sqrt", math_sqrt, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "cbrt", math_cbrt, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "frexp", math_frexp, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "ldexp", math_ldexp, MRB_ARGS_REQ(2)); mrb_define_module_function(mrb, mrb_math, "hypot", math_hypot, MRB_ARGS_REQ(2)); mrb_define_module_function(mrb, mrb_math, "erf", math_erf, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "erfc", math_erfc, MRB_ARGS_REQ(1)); }
/* * 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); }
static mrb_value flo_round(mrb_state *mrb, mrb_value num) { double number, f; mrb_int ndigits = 0; mrb_int i; mrb_get_args(mrb, "|i", &ndigits); number = mrb_float(num); if (0 < ndigits && (isinf(number) || isnan(number))) { return num; } mrb_check_num_exact(mrb, number); f = 1.0; i = ndigits >= 0 ? ndigits : -ndigits; while (--i >= 0) f = f*10.0; if (isinf(f)) { if (ndigits < 0) number = 0; } else { double d; if (ndigits < 0) number /= f; else number *= f; /* home-made inline implementation of round(3) */ if (number > 0.0) { d = floor(number); number = d + (number - d >= 0.5); } else if (number < 0.0) { d = ceil(number); number = d - (d - number >= 0.5); } if (ndigits < 0) number *= f; else number /= f; } if (ndigits > 0) { if (!isfinite(number)) return num; return mrb_float_value(mrb, number); } return mrb_fixnum_value((mrb_int)number); }
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 }
/* ------------------------------------------------------------------------*/ void mrb_init_math(mrb_state *mrb) { struct RClass *mrb_math; mrb_math = mrb_define_module(mrb, "Math"); #ifdef M_PI mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(M_PI)); #else mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(atan(1.0)*4.0)); #endif #ifdef M_E mrb_define_const(mrb, mrb_math, "E", mrb_float_value(M_E)); #else mrb_define_const(mrb, mrb_math, "E", mrb_float_value(exp(1.0))); #endif #ifdef MRB_USE_FLOAT mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(1e-5)); #else mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(1e-12)); #endif mrb_define_module_function(mrb, mrb_math, "sin", math_sin, ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "cos", math_cos, ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "tan", math_tan, ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "asin", math_asin, ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "acos", math_acos, ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "atan", math_atan, ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "atan2", math_atan2, ARGS_REQ(2)); mrb_define_module_function(mrb, mrb_math, "sinh", math_sinh, ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "cosh", math_cosh, ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "tanh", math_tanh, ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "asinh", math_asinh, ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "acosh", math_acosh, ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "atanh", math_atanh, ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "exp", math_exp, ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "log", math_log, ARGS_REQ(1)|ARGS_OPT(1)); mrb_define_module_function(mrb, mrb_math, "log2", math_log2, ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "log10", math_log10, ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "sqrt", math_sqrt, ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "cbrt", math_cbrt, ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "frexp", math_frexp, ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "ldexp", math_ldexp, ARGS_REQ(2)); mrb_define_module_function(mrb, mrb_math, "hypot", math_hypot, ARGS_REQ(2)); mrb_define_module_function(mrb, mrb_math, "erf", math_erf, ARGS_REQ(1)); mrb_define_module_function(mrb, mrb_math, "erfc", math_erfc, ARGS_REQ(1)); }
static mrb_value mrb_sample_buffer_get_method(mrb_state *mrb, mrb_value self) { mrb_int i; mrb_sample_buffer *b; b = mrb_data_check_get_ptr(mrb, self, &mrb_sample_buffer_type); mrb_get_args(mrb, "i", &i); if (0 <= i && i < b->len) { return mrb_float_value(mrb, MRB_SAMPLE_BUFFER_DATA(b)[i]); } else { return mrb_nil_value(); } }
mrb_value mrb_redis_zadd(mrb_state *mrb, mrb_value self) { mrb_value key, member; mrb_float score; redisContext *rc = DATA_PTR(self); mrb_get_args(mrb, "ofo", &key, &score, &member); mrb_value score_str = mrb_float_to_str(mrb, mrb_float_value(mrb, score), "%f"); const char *argv[] = {"ZADD", RSTRING_PTR(key), RSTRING_PTR(score_str), RSTRING_PTR(member)}; size_t lens[] = {4, RSTRING_LEN(key), RSTRING_LEN(score_str), RSTRING_LEN(member)}; redisReply *rs = redisCommandArgv(rc, 4, argv, lens); freeReplyObject(rs); return self; }
static mrb_value mrb_sample_buffer_set_method(mrb_state *mrb, mrb_value self) { mrb_int i; mrb_float f; mrb_sample_buffer *b = mrb_data_check_get_ptr(mrb, self, &mrb_sample_buffer_type); mrb_get_args(mrb, "if", &i, &f); if (0 <= i && i < b->len) { MRB_SAMPLE_BUFFER_DATA(b)[i] = f; return mrb_float_value(mrb, f); } else { mrb_raise(mrb, E_ARGUMENT_ERROR, "Index out of bounds"); } }
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 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 flo_mul(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_real(y) * mrb_float(x), mrb_imag(y) * mrb_float(x) ); } #endif return mrb_float_value(mrb, mrb_float(x) * mrb_to_flo(mrb, y)); }
static mrb_value mrb_cp_contact_points_value(mrb_state *mrb, cpContactPointSet *contact_point_set) { mrb_value points; mrb_value point; int i; points = mrb_ary_new_capa(mrb, contact_point_set->count); for (i = 0; i < contact_point_set->count; ++i) { point = mrb_obj_new(mrb, mrb_cp_contact_point_class, 0, NULL); mrb_iv_set(mrb, point, mrb_intern_lit(mrb, "@point_a"), mrb_cp_vect_value(mrb, contact_point_set->points[i].pointA)); mrb_iv_set(mrb, point, mrb_intern_lit(mrb, "@point_b"), mrb_cp_vect_value(mrb, contact_point_set->points[i].pointB)); mrb_iv_set(mrb, point, mrb_intern_lit(mrb, "@distance"), mrb_float_value(mrb, contact_point_set->points[i].distance)); mrb_ary_set(mrb, points, i, point); } return points; }
/* ------------------------------------------------------------------------*/ void mrb_mruby_math_gem_init(mrb_state* mrb) { mrb->define_module("Math") #ifdef M_PI .define_const("PI", mrb_float_value(M_PI)) #else .define_const("PI", mrb_float_value(atan(1.0)*4.0)) #endif #ifdef M_E .define_const("E", mrb_float_value(M_E)) #else .define_const("E", mrb_float_value(exp(1.0))) #endif #ifdef MRB_USE_FLOAT .define_const("TOLERANCE", mrb_float_value(1e-5)) #else .define_const("TOLERANCE", mrb_float_value(1e-12)) #endif .define_module_function("sin", math_sin, MRB_ARGS_REQ(1)) .define_module_function("cos", math_cos, MRB_ARGS_REQ(1)) .define_module_function("tan", math_tan, MRB_ARGS_REQ(1)) .define_module_function("asin", math_asin, MRB_ARGS_REQ(1)) .define_module_function("acos", math_acos, MRB_ARGS_REQ(1)) .define_module_function("atan", math_atan, MRB_ARGS_REQ(1)) .define_module_function("atan2", math_atan2, MRB_ARGS_REQ(2)) .define_module_function("sinh", math_sinh, MRB_ARGS_REQ(1)) .define_module_function("cosh", math_cosh, MRB_ARGS_REQ(1)) .define_module_function("tanh", math_tanh, MRB_ARGS_REQ(1)) .define_module_function("asinh", math_asinh, MRB_ARGS_REQ(1)) .define_module_function("acosh", math_acosh, MRB_ARGS_REQ(1)) .define_module_function("atanh", math_atanh, MRB_ARGS_REQ(1)) .define_module_function("exp", math_exp, MRB_ARGS_REQ(1)) .define_module_function("log", math_log, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)) .define_module_function("log2", math_log2, MRB_ARGS_REQ(1)) .define_module_function("log10", math_log10, MRB_ARGS_REQ(1)) .define_module_function("sqrt", math_sqrt, MRB_ARGS_REQ(1)) .define_module_function("cbrt", math_cbrt, MRB_ARGS_REQ(1)) .define_module_function("frexp", math_frexp, MRB_ARGS_REQ(1)) .define_module_function("ldexp", math_ldexp, MRB_ARGS_REQ(2)) .define_module_function("hypot", math_hypot, MRB_ARGS_REQ(2)) .define_module_function("erf", math_erf, MRB_ARGS_REQ(1)) .define_module_function("erfc", math_erfc, MRB_ARGS_REQ(1)) .fin(); }
static mrb_value json_value_to_mrb_value(mrb_state* mrb, JSON_Value* value) { ARENA_SAVE; switch (json_value_get_type(value)) { case JSONError: case JSONNull: return mrb_nil_value(); case JSONString: return mrb_str_new_cstr(mrb, json_value_get_string(value)); case JSONNumber: return mrb_float_value(json_value_get_number(value)); case JSONObject: { mrb_value hash = mrb_hash_new(mrb); JSON_Object* object = json_value_get_object(value); size_t count = json_object_get_count(object); int n; for (n = 0; n < count; n++) { const char* name = json_object_get_name(object, n); mrb_hash_set(mrb, hash, mrb_str_new_cstr(mrb, name), json_value_to_mrb_value(mrb, json_object_get_value(object, name))); } return hash; } case JSONArray: { mrb_value ary; ary = mrb_ary_new(mrb); JSON_Array* array = json_value_get_array(value); size_t count = json_array_get_count(array); int n; for (n = 0; n < count; n++) { JSON_Value* elem = json_array_get_value(array, n); mrb_ary_push(mrb, ary, json_value_to_mrb_value(mrb, elem)); } return ary; } case JSONBoolean: if (json_value_get_boolean(value)) { return mrb_true_value(); } return mrb_false_value(); default: mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument"); } return mrb_nil_value(); }
static mrb_value mrb_sample_buffer_each_method(mrb_state *mrb, mrb_value self) { mrb_int i; mrb_value block; mrb_bool block_given; mrb_sample_buffer *b = mrb_data_check_get_ptr(mrb, self, &mrb_sample_buffer_type); mrb_get_args(mrb, "|&?", &block, &block_given); if (block_given) { for (i = 0; i < b->len; ++i) { mrb_yield(mrb, block, mrb_float_value(mrb, MRB_SAMPLE_BUFFER_DATA(b)[i])); } return self; } else { return mrb_funcall(mrb, self, "enum_for", 1, mrb_symbol_value(mrb_intern_lit(mrb, "each"))); } }
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 }
/* * call-seq: * Math.log(numeric) -> float * Math.log(num,base) -> float * * Returns the natural logarithm of <i>numeric</i>. * If additional second argument is given, it will be the base * of logarithm. * * Math.log(1) #=> 0.0 * Math.log(Math::E) #=> 1.0 * Math.log(Math::E**3) #=> 3.0 * Math.log(12,3) #=> 2.2618595071429146 * */ static mrb_value math_log(mrb_state *mrb, mrb_value obj) { mrb_float x, base; int argc; argc = mrb_get_args(mrb, "f|f", &x, &base); if (x < 0.0) { domain_error(mrb, "log"); } x = log(x); if (argc == 2) { if (base < 0.0) { domain_error(mrb, "log"); } x /= log(base); } return mrb_float_value(mrb, x); }
static mrb_value mrb_time_minus(mrb_state *mrb, mrb_value self) { mrb_float f; mrb_value other; struct mrb_time *tm, *tm2; mrb_get_args(mrb, "o", &other); tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time); if (tm2) { f = (mrb_float)(tm->sec - tm2->sec) + (mrb_float)(tm->usec - tm2->usec) / 1.0e6; return mrb_float_value(mrb, f); } else { mrb_get_args(mrb, "f", &f); return mrb_time_make(mrb, mrb_obj_class(mrb, self), (double)tm->sec-f, (double)tm->usec, tm->timezone); } }
static mrb_value mrb_time_minus(mrb_state *mrb, mrb_value self) { mrb_float f; mrb_value other; struct mrb_time *tm, *tm2; mrb_get_args(mrb, "o", &other); tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type); if (!tm) return mrb_nil_value(); tm2 = (struct mrb_time *)mrb_get_datatype(mrb, other, &mrb_time_type); if (tm2) { f = (mrb_float)(tm->sec - tm2->sec) + (mrb_float)(tm->usec - tm2->usec) / 1.0e6; return mrb_float_value(f); } else { mrb_get_args(mrb, "f", &f); return mrb_time_make(mrb, mrb_obj_class(mrb, self), (double)tm->sec-f, tm->usec, tm->timezone); } }
static mrb_value flo_round(mrb_state *mrb, mrb_value num) { double number, f; mrb_int ndigits = 0; int i; mrb_get_args(mrb, "|i", &ndigits); number = mrb_float(num); f = 1.0; i = abs(ndigits); while (--i >= 0) f = f*10.0; if (isinf(f)) { if (ndigits < 0) number = 0; } else { double d; if (ndigits < 0) number /= f; else number *= f; /* home-made inline implementation of round(3) */ if (number > 0.0) { d = floor(number); number = d + (number - d >= 0.5); } else if (number < 0.0) { d = ceil(number); number = d - (d - number >= 0.5); } if (ndigits < 0) number *= f; else number /= f; } if (ndigits > 0) return mrb_float_value(number); return mrb_fixnum_value((mrb_int)number); }