@JRubyMethod(name = "round", compat = CompatVersion.RUBY1_9) public IRubyObject round19(ThreadContext context, IRubyObject arg) { int ndigits = RubyNumeric.num2int(arg); if (ndigits > 0) return RubyKernel.new_float(this, this); if (ndigits == 0) return this; Ruby runtime = context.runtime; long bytes = (this instanceof RubyFixnum) ? 8 : RubyFixnum.fix2long(callMethod("size")); /* If 10**N/2 > this, return 0 */ /* We have log_256(10) > 0.415241 and log_256(1/2)=-0.125 */ if (-0.415241 * ndigits - 0.125 > bytes) { return RubyFixnum.zero(runtime); } IRubyObject f = Numeric.int_pow(context, 10, -ndigits); if (this instanceof RubyFixnum && f instanceof RubyFixnum) { long x = ((RubyFixnum) this).getLongValue(); long y = ((RubyFixnum) f).getLongValue(); boolean neg = x < 0; if (neg) x = -x; x = (x + y / 2) / y * y; if (neg) x = -x; return RubyFixnum.newFixnum(runtime, x); } else if (f instanceof RubyFloat) { return RubyFixnum.zero(runtime); } else { IRubyObject h = f.callMethod(context, "/", RubyFixnum.two(runtime)); IRubyObject r = callMethod(context, "%", f); IRubyObject n = callMethod(context, "-", r); String op = callMethod(context, "<", RubyFixnum.zero(runtime)).isTrue() ? "<=" : "<"; if (!r.callMethod(context, op, h).isTrue()) n = n.callMethod(context, "+", f); return n; } }
@Override public IRubyObject set(IRubyObject value) { runtime .getWarnings() .warnOnce(ID.SAFE_NOT_SUPPORTED, "SAFE levels are not supported in JRuby"); return RubyFixnum.zero(runtime); }
@JRubyMethod(name = "seek", required = 1, optional = 1, frame = true) public IRubyObject seek(IRubyObject[] args) { // MRI 1.8.7 behavior: // checkOpen(); checkFinalized(); long amount = RubyNumeric.num2long(args[0]); int whence = Stream.SEEK_SET; long newPosition = pos; if (args.length > 1 && !args[0].isNil()) whence = RubyNumeric.fix2int(args[1]); if (whence == Stream.SEEK_CUR) { newPosition += amount; } else if (whence == Stream.SEEK_END) { newPosition = internal.getByteList().length() + amount; } else { newPosition = amount; } if (newPosition < 0) throw getRuntime().newErrnoEINVALError(); pos = newPosition; eof = false; return RubyFixnum.zero(getRuntime()); }
private IRubyObject stepCommon(ThreadContext context, IRubyObject step, Block block) { final Ruby runtime = context.getRuntime(); long unit = RubyNumeric.num2long(step); if (unit < 0) throw runtime.newArgumentError("step can't be negative"); if (begin instanceof RubyFixnum && end instanceof RubyFixnum) { if (unit == 0) throw runtime.newArgumentError("step can't be 0"); fixnumStep(context, runtime, unit, block); } else { IRubyObject tmp = begin.checkStringType(); if (!tmp.isNil()) { if (unit == 0) throw runtime.newArgumentError("step can't be 0"); // rb_iterate((VALUE(*)_((VALUE)))str_step, (VALUE)args, step_i, (VALUE)iter); StepBlockCallBack callback = new StepBlockCallBack(block, RubyFixnum.one(runtime), step); Block blockCallback = CallBlock.newCallClosure( this, runtime.getRange(), Arity.singleArgument(), callback, context); ((RubyString) tmp).uptoCommon(context, end, isExclusive, blockCallback); } else if (begin instanceof RubyNumeric) { if (equalInternal(context, step, RubyFixnum.zero(runtime))) throw runtime.newArgumentError("step can't be 0"); numericStep(context, runtime, step, block); } else { if (unit == 0) throw runtime.newArgumentError("step can't be 0"); if (!begin.respondsTo("succ")) throw runtime.newTypeError("can't iterate from " + begin.getMetaClass().getName()); // range_each_func(range, step_i, b, e, args); rangeEach(context, new StepBlockCallBack(block, RubyFixnum.one(runtime), step)); } } return this; }
/** num_abs */ @JRubyMethod(name = "abs") public IRubyObject abs(ThreadContext context) { if (callMethod(context, "<", RubyFixnum.zero(getRuntime())).isTrue()) { return callMethod(context, "-@"); } return this; }
/** num_cmp */ @JRubyMethod(name = "<=>") public IRubyObject op_cmp(IRubyObject other) { if (this == other) { // won't hurt fixnums return RubyFixnum.zero(getRuntime()); } return getRuntime().getNil(); }
private IRubyObject rangeLe(ThreadContext context, IRubyObject a, IRubyObject b) { IRubyObject result = a.callMethod(context, "<=>", b); if (result.isNil()) return null; int c = RubyComparable.cmpint(context, result, a, b); if (c == 0) return RubyFixnum.zero(getRuntime()); return c < 0 ? getRuntime().getTrue() : null; }
@JRubyMethod(name = "odd?") public RubyBoolean odd_p(ThreadContext context) { Ruby runtime = context.runtime; if (callMethod(context, "%", RubyFixnum.two(runtime)) != RubyFixnum.zero(runtime)) { return runtime.getTrue(); } return runtime.getFalse(); }
@Override public RubyFixnum id() { if ((flags & FALSE_F) == 0) { return RubyFixnum.newFixnum(getRuntime(), 2); } else { return RubyFixnum.zero(getRuntime()); } }
@JRubyMethod(name = "even?") public RubyBoolean even_p(ThreadContext context) { Ruby runtime = context.getRuntime(); if (callMethod(context, "%", RubyFixnum.two(runtime)) == RubyFixnum.zero(runtime)) { return runtime.getTrue(); } return runtime.getFalse(); }
@JRubyMethod(name = "round", optional = 1) public IRubyObject round(ThreadContext context, IRubyObject[] args) { if (args.length == 0) return round(); // truncate floats. double digits = num2long(args[0]); double magnifier = Math.pow(10.0, Math.abs(digits)); double number = value; if (Double.isInfinite(value)) { if (digits <= 0) throw getRuntime().newFloatDomainError(value < 0 ? "-Infinity" : "Infinity"); return this; } if (Double.isNaN(value)) { if (digits <= 0) throw getRuntime().newFloatDomainError("NaN"); return this; } // MRI flo_round logic to deal with huge precision numbers. double binexp = Math.ceil(Math.log(value) / Math.log(2)); if (digits >= (DIG + 2) - (binexp > 0 ? binexp / 4 : binexp / 3 - 1)) { return RubyFloat.newFloat(context.runtime, number); } if (digits < -(binexp > 0 ? binexp / 3 + 1 : binexp / 4)) { return RubyFixnum.zero(context.runtime); } if (Double.isInfinite(magnifier)) { if (digits < 0) number = 0; } else { if (digits < 0) { number /= magnifier; } else { number *= magnifier; } number = Math.round(Math.abs(number)) * Math.signum(number); if (digits < 0) { number *= magnifier; } else { number /= magnifier; } } if (digits > 0) { return RubyFloat.newFloat(context.runtime, number); } else { if (number > Long.MAX_VALUE || number < Long.MIN_VALUE) { // The only way to get huge precise values with BigDecimal is // to convert the double to String first. BigDecimal roundedNumber = new BigDecimal(Double.toString(number)); return RubyBignum.newBignum(context.runtime, roundedNumber.toBigInteger()); } return dbl2num(context.runtime, (long) number); } }
void call(ThreadContext context, IRubyObject arg) { if (iter instanceof RubyFixnum) { iter = RubyFixnum.newFixnum(context.getRuntime(), ((RubyFixnum) iter).getLongValue() - 1); } else { iter = iter.callMethod(context, "-", RubyFixnum.one(context.getRuntime())); } if (iter == RubyFixnum.zero(context.getRuntime())) { block.yield(context, arg); iter = step; } }
/** numeric_arg */ @JRubyMethod(name = {"arg", "angle", "phase"}) public IRubyObject arg(ThreadContext context) { double value = this.getDoubleValue(); if (Double.isNaN(value)) { return this; } if (f_negative_p(context, this) || (value == 0.0 && 1 / value == Double.NEGATIVE_INFINITY)) { // negative or -0.0 return context.runtime.getMath().getConstant("PI"); } return RubyFixnum.zero(context.runtime); }
/** rb_cmpint */ public static int cmpint(ThreadContext context, IRubyObject val, IRubyObject a, IRubyObject b) { if (val.isNil()) cmperr(a, b); if (val instanceof RubyFixnum) return RubyNumeric.fix2int((RubyFixnum) val); if (val instanceof RubyBignum) return ((RubyBignum) val).getValue().signum() == -1 ? -1 : 1; RubyFixnum zero = RubyFixnum.zero(context.runtime); if (val.callMethod(context, ">", zero).isTrue()) return 1; if (val.callMethod(context, "<", zero).isTrue()) return -1; return 0; }
@JRubyMethod(name = "step", frame = true, compat = CompatVersion.RUBY1_9) public IRubyObject step19(final ThreadContext context, IRubyObject step, final Block block) { Ruby runtime = context.getRuntime(); if (!block.isGiven()) return enumeratorize(runtime, this, "step", step); if (!(step instanceof RubyNumeric)) step = step.convertToInteger("to_int"); IRubyObject zero = RubyFixnum.zero(runtime); if (step.callMethod(context, "<", zero).isTrue()) throw runtime.newArgumentError("step can't be negative"); if (!step.callMethod(context, ">", zero).isTrue()) throw runtime.newArgumentError("step can't be 0"); return stepCommon19(context, step, block); }
/** 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); } }
/** num_remainder */ @JRubyMethod(name = "remainder") public IRubyObject remainder(ThreadContext context, IRubyObject dividend) { IRubyObject z = callMethod(context, "%", dividend); IRubyObject x = this; RubyFixnum zero = RubyFixnum.zero(getRuntime()); if (!equalInternal(context, z, zero) && ((x.callMethod(context, "<", zero).isTrue() && dividend.callMethod(context, ">", zero).isTrue()) || (x.callMethod(context, ">", zero).isTrue() && dividend.callMethod(context, "<", zero).isTrue()))) { return z.callMethod(context, "-", dividend); } else { return z; } }
private void rangeEach(ThreadContext context, RangeCallBack callback) { IRubyObject v = begin; if (isExclusive) { while (rangeLt(context, v, end) != null) { callback.call(context, v); v = v.callMethod(context, "succ"); } } else { IRubyObject c; while ((c = rangeLe(context, v, end)) != null && c.isTrue()) { callback.call(context, v); if (c == RubyFixnum.zero(getRuntime())) break; v = v.callMethod(context, "succ"); } } }
@JRubyMethod public IRubyObject times(ThreadContext context, Block block) { if (block.isGiven()) { Ruby runtime = context.getRuntime(); IRubyObject i = RubyFixnum.zero(runtime); RubyFixnum one = RubyFixnum.one(runtime); while (true) { if (!i.callMethod(context, "<", this).isTrue()) { break; } block.yield(context, i); i = i.callMethod(context, "+", one); } return this; } else { return enumeratorize(context.getRuntime(), this, "times"); } }
/** num_step_scan_args */ private IRubyObject[] scanStepArgs(ThreadContext context, IRubyObject[] args) { IRubyObject to = context.runtime.getNil(); IRubyObject step = context.runtime.newFixnum(1); if (args.length >= 1) to = args[0]; if (args.length >= 2) step = args[1]; // TODO: Fold kwargs into the @JRubyMethod decorator IRubyObject[] kwargs = ArgsUtil.extractKeywordArgs(context, args, validStepArgs); if (kwargs != null) { to = kwargs[0]; step = kwargs[1]; if (!to.isNil() && args.length > 1) { throw context.runtime.newArgumentError("to is given twice"); } if (!step.isNil() && args.length > 2) { throw context.runtime.newArgumentError("step is given twice"); } } else { if (RubyBasicObject.equalInternal(context, step, RubyFixnum.zero(context.runtime))) { throw context.runtime.newArgumentError("step can't be 0"); } if (step.isNil()) { throw context.runtime.newTypeError("step must be numeric"); } } if (step.isNil()) { step = RubyFixnum.one(context.runtime); } if (to.isNil()) { if (f_negative_p(context, step)) { to = RubyFloat.newFloat(context.runtime, Double.NEGATIVE_INFINITY); } else { to = RubyFloat.newFloat(context.runtime, Double.POSITIVE_INFINITY); } } return new IRubyObject[] {to, step}; }
private RubyString getCorrectKey(IRubyObject key, ThreadContext context) { RubyString originalKey = key.convertToString(); RubyString actualKey = originalKey; Ruby runtime = context.getRuntime(); if (Platform.IS_WINDOWS) { // this is a rather ugly hack, but similar to MRI. See hash.c:ruby_setenv and similar in MRI // we search all keys for a case-insensitive match, and use that RubyArray keys = super.keys(); for (int i = 0; i < keys.size(); i++) { RubyString candidateKey = keys.eltInternal(i).convertToString(); if (candidateKey .casecmp(context, originalKey) .op_equal(context, RubyFixnum.zero(runtime)) .isTrue()) { actualKey = candidateKey; break; } } } return actualKey; }
@JRubyMethod(name = "fsync") public IRubyObject fsync() { return RubyFixnum.zero(getRuntime()); }
/** num_imaginary */ @JRubyMethod(name = "i") public IRubyObject num_imaginary(ThreadContext context) { return RubyComplex.newComplexRaw(context.runtime, RubyFixnum.zero(context.runtime), this); }
/** num_uminus */ @JRubyMethod(name = "-@") public IRubyObject op_uminus(ThreadContext context) { RubyArray ary = RubyFixnum.zero(context.runtime).doCoerce(context, this, true); return ary.eltInternal(0).callMethod(context, "-", ary.eltInternal(1)); }
@JRubyMethod(name = "avail_in") public IRubyObject avail_in() { return RubyFixnum.zero(getRuntime()); }
@JRubyMethod(name = "step", frame = true, compat = CompatVersion.RUBY1_9) public IRubyObject step19(final ThreadContext context, final Block block) { return block.isGiven() ? stepCommon19(context, RubyFixnum.zero(context.getRuntime()), block) : enumeratorize(context.getRuntime(), this, "step"); }
/** num_zero_p */ @JRubyMethod(name = "zero?") public IRubyObject zero_p(ThreadContext context) { return equalInternal(context, this, RubyFixnum.zero(getRuntime())) ? getRuntime().getTrue() : getRuntime().getFalse(); }
@JRubyMethod(name = "rewind") public IRubyObject rewind() { doRewind(); return RubyFixnum.zero(getRuntime()); }
@JRubyMethod(name = "pos") public IRubyObject pos() { return RubyFixnum.zero(getRuntime()); }
public static RubyNumeric intervalStepSize( ThreadContext context, IRubyObject from, IRubyObject to, IRubyObject step, boolean excludeLast) { Ruby runtime = context.runtime; if (from instanceof RubyFixnum && to instanceof RubyFixnum && step instanceof RubyFixnum) { long diff = ((RubyFixnum) step).getLongValue(); if (diff == 0) { return RubyFloat.newFloat(runtime, Double.POSITIVE_INFINITY); } long delta = ((RubyFixnum) to).getLongValue() - ((RubyFixnum) from).getLongValue(); if (diff < 0) { diff = -diff; delta = -delta; } if (excludeLast) { delta--; } if (delta < 0) { return runtime.newFixnum(0); } long result = delta / diff; return new RubyFixnum(runtime, result >= 0 ? result + 1 : 0); } else if (from instanceof RubyFloat || to instanceof RubyFloat || step instanceof RubyFloat) { double n = floatStepSize( from.convertToFloat().getDoubleValue(), to.convertToFloat().getDoubleValue(), step.convertToFloat().getDoubleValue(), excludeLast); if (Double.isInfinite(n)) { return runtime.newFloat(n); } else { return runtime.newFloat(n).convertToInteger(); } } else { String cmpString = ">"; RubyFixnum zero = RubyFixnum.zero(runtime); IRubyObject comparison = zero.coerceCmp(context, "<=>", step); switch (RubyComparable.cmpint(context, comparison, step, zero)) { case 0: return RubyFloat.newFloat(runtime, Float.POSITIVE_INFINITY); case 1: cmpString = "<"; break; } if (from.callMethod(context, cmpString, to).isTrue()) { return RubyFixnum.zero(runtime); } IRubyObject diff = to.callMethod(context, "-", from); IRubyObject result = diff.callMethod(context, "div", step); if (!excludeLast || from.callMethod(context, "+", result.callMethod(context, "*", step)) .callMethod(context, cmpString, to) .isTrue()) { result = result.callMethod(context, "+", RubyFixnum.newFixnum(runtime, 1)); } return (RubyNumeric) result; } }