/** flo_cmp */ @JRubyMethod(name = "<=>", required = 1) public IRubyObject op_cmp(ThreadContext context, IRubyObject other) { switch (other.getMetaClass().getClassIndex()) { case FIXNUM: case BIGNUM: if (Double.isInfinite(value)) { return value > 0.0 ? RubyFixnum.one(getRuntime()) : RubyFixnum.minus_one(getRuntime()); } case FLOAT: double b = ((RubyNumeric) other).getDoubleValue(); return dbl_cmp(getRuntime(), value, b); default: if (Double.isInfinite(value) && other.respondsTo("infinite?")) { IRubyObject infinite = other.callMethod(context, "infinite?"); if (infinite.isNil()) { return value > 0.0 ? RubyFixnum.one(getRuntime()) : RubyFixnum.minus_one(getRuntime()); } else { int sign = RubyFixnum.fix2int(infinite); if (sign > 0) { if (value > 0.0) { return RubyFixnum.zero(getRuntime()); } else { return RubyFixnum.minus_one(getRuntime()); } } else { if (value < 0.0) { return RubyFixnum.zero(getRuntime()); } else { return RubyFixnum.one(getRuntime()); } } } } return coerceCmp(context, "<=>", other); } }
/** rb_dbl_cmp (numeric.c) */ public static IRubyObject dbl_cmp(Ruby runtime, double a, double b) { if (Double.isNaN(a) || Double.isNaN(b)) return runtime.getNil(); return a == b ? RubyFixnum.zero(runtime) : a > b ? RubyFixnum.one(runtime) : RubyFixnum.minus_one(runtime); }