@JRubyMethod(name = "to_r") public IRubyObject to_r(ThreadContext context) { long[] exp = new long[1]; double f = frexp(value, exp); f = ldexp(f, DBL_MANT_DIG); long n = exp[0] - DBL_MANT_DIG; Ruby runtime = context.runtime; IRubyObject rf = RubyNumeric.dbl2num(runtime, f); IRubyObject rn = RubyFixnum.newFixnum(runtime, n); return f_mul(context, rf, f_expt(context, RubyFixnum.newFixnum(runtime, FLT_RADIX), rn)); }
/** float_rationalize */ @JRubyMethod(name = "rationalize", optional = 1) public IRubyObject rationalize(ThreadContext context, IRubyObject[] args) { if (f_negative_p(context, this)) return f_negate(context, ((RubyFloat) f_abs(context, this)).rationalize(context, args)); Ruby runtime = context.runtime; RubyFixnum one = RubyFixnum.one(runtime); RubyFixnum two = RubyFixnum.two(runtime); IRubyObject eps, a, b; if (args.length != 0) { eps = f_abs(context, args[0]); a = f_sub(context, this, eps); b = f_add(context, this, eps); } else { long[] exp = new long[1]; double f = frexp(value, exp); f = ldexp(f, DBL_MANT_DIG); long n = exp[0] - DBL_MANT_DIG; IRubyObject rf = RubyNumeric.dbl2num(runtime, f); IRubyObject rn = RubyFixnum.newFixnum(runtime, n); if (f_zero_p(context, rf) || !(f_negative_p(context, rn) || f_zero_p(context, rn))) return RubyRational.newRationalRaw(runtime, f_lshift(context, rf, rn)); a = RubyRational.newRationalRaw( runtime, f_sub(context, f_mul(context, two, rf), one), f_lshift(context, one, f_sub(context, one, rn))); b = RubyRational.newRationalRaw( runtime, f_add(context, f_mul(context, two, rf), one), f_lshift(context, one, f_sub(context, one, rn))); } if (invokedynamic(context, a, OP_EQUAL, b).isTrue()) return f_to_r(context, this); IRubyObject[] ary = new IRubyObject[2]; ary[0] = a; ary[1] = b; IRubyObject[] ans = nurat_rationalize_internal(context, ary); return RubyRational.newRationalRaw(runtime, ans[0], ans[1]); }