Example #1
0
  @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;
    }
  }
Example #2
0
 @Override
 public IRubyObject set(IRubyObject value) {
   runtime
       .getWarnings()
       .warnOnce(ID.SAFE_NOT_SUPPORTED, "SAFE levels are not supported in JRuby");
   return RubyFixnum.zero(runtime);
 }
Example #3
0
  @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());
  }
Example #4
0
  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;
  }
Example #5
0
 /** num_abs */
 @JRubyMethod(name = "abs")
 public IRubyObject abs(ThreadContext context) {
   if (callMethod(context, "<", RubyFixnum.zero(getRuntime())).isTrue()) {
     return callMethod(context, "-@");
   }
   return this;
 }
Example #6
0
 /** num_cmp */
 @JRubyMethod(name = "<=>")
 public IRubyObject op_cmp(IRubyObject other) {
   if (this == other) { // won't hurt fixnums
     return RubyFixnum.zero(getRuntime());
   }
   return getRuntime().getNil();
 }
Example #7
0
 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;
 }
Example #8
0
 @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();
 }
Example #9
0
 @Override
 public RubyFixnum id() {
   if ((flags & FALSE_F) == 0) {
     return RubyFixnum.newFixnum(getRuntime(), 2);
   } else {
     return RubyFixnum.zero(getRuntime());
   }
 }
Example #10
0
 @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();
 }
Example #11
0
  @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);
    }
  }
Example #12
0
 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;
   }
 }
Example #13
0
 /** 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);
 }
Example #14
0
  /** 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;
  }
Example #15
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);
  }
Example #16
0
  /** 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);
    }
  }
Example #17
0
  /** 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;
    }
  }
Example #18
0
 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");
     }
   }
 }
Example #19
0
 @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");
   }
 }
Example #20
0
  /** 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};
  }
Example #21
0
 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;
 }
Example #22
0
 @JRubyMethod(name = "fsync")
 public IRubyObject fsync() {
   return RubyFixnum.zero(getRuntime());
 }
Example #23
0
 /** num_imaginary */
 @JRubyMethod(name = "i")
 public IRubyObject num_imaginary(ThreadContext context) {
   return RubyComplex.newComplexRaw(context.runtime, RubyFixnum.zero(context.runtime), this);
 }
Example #24
0
 /** 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));
 }
Example #25
0
 @JRubyMethod(name = "avail_in")
 public IRubyObject avail_in() {
   return RubyFixnum.zero(getRuntime());
 }
Example #26
0
 @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");
 }
Example #27
0
 /** num_zero_p */
 @JRubyMethod(name = "zero?")
 public IRubyObject zero_p(ThreadContext context) {
   return equalInternal(context, this, RubyFixnum.zero(getRuntime()))
       ? getRuntime().getTrue()
       : getRuntime().getFalse();
 }
Example #28
0
 @JRubyMethod(name = "rewind")
 public IRubyObject rewind() {
   doRewind();
   return RubyFixnum.zero(getRuntime());
 }
Example #29
0
 @JRubyMethod(name = "pos")
 public IRubyObject pos() {
   return RubyFixnum.zero(getRuntime());
 }
Example #30
0
  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;
    }
  }