static VALUE f_round_common(int argc, VALUE *argv, VALUE self, VALUE (*func)(VALUE, SEL)) { VALUE n, b, s; if (argc == 0) return (*func)(self, NULL); rb_scan_args(argc, argv, "01", &n); if (!k_integer_p(n)) rb_raise(rb_eTypeError, "not an integer"); b = f_expt(INT2FIX(10), n); s = f_mul(self, b); s = (*func)(s, NULL); s = f_div(f_rational_new_bang1(CLASS_OF(self), s), b); if (f_lt_p(n, ONE)) s = f_to_i(s); return s; }
inline static long i_ilog2(VALUE x) { long q, r, fx; assert(!f_lt_p(x, ONE)); q = (NUM2LONG(f_size(x)) - sizeof(long)) * 8 + 1; if (q > 0) x = f_rshift(x, LONG2NUM(q)); fx = NUM2LONG(x); r = -1; while (fx) { fx >>= 1; r += 1; } return q + r; }