Beispiel #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;
    ndigits = -ndigits;
    Ruby runtime = context.getRuntime();
    if (ndigits < 0) throw runtime.newArgumentError("ndigits out of range");
    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 {
      IRubyObject h = f.callMethod(context, "/", RubyFixnum.two(runtime));
      IRubyObject r = callMethod(context, "%", f);
      IRubyObject n = callMethod(context, "-", r);
      if (!r.callMethod(context, "<", h).isTrue()) n = n.callMethod(context, "+", f);
      return n;
    }
  }
Beispiel #2
0
 private IRubyObject stepCommon19(ThreadContext context, IRubyObject step, Block block) {
   Ruby runtime = context.getRuntime();
   if (begin instanceof RubyFixnum && end instanceof RubyFixnum && step instanceof RubyFixnum) {
     fixnumStep(context, runtime, ((RubyFixnum) step).getLongValue(), block);
   } else if (begin instanceof RubyFloat
       || end instanceof RubyFloat
       || step instanceof RubyFloat) {
     RubyNumeric.floatStep19(context, runtime, begin, end, step, isExclusive, block);
   } else if (begin instanceof RubyNumeric
       || !checkIntegerType(runtime, begin, "to_int").isNil()
       || !checkIntegerType(runtime, end, "to_int").isNil()) {
     numericStep19(context, runtime, step, block);
   } else {
     IRubyObject tmp = begin.checkStringType();
     if (!tmp.isNil()) {
       StepBlockCallBack callback = new StepBlockCallBack(block, RubyFixnum.one(runtime), step);
       Block blockCallback =
           CallBlock.newCallClosure(
               this, runtime.getRange(), Arity.singleArgument(), callback, context);
       ((RubyString) tmp).uptoCommon19(context, end, isExclusive, blockCallback);
     } else {
       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;
 }
Beispiel #3
0
 private static void fixnumStep(
     ThreadContext context, Ruby runtime, long from, long to, long step, Block block) {
   // We must avoid integer overflows in "i += step".
   if (step >= 0) {
     long tov = Long.MAX_VALUE - step;
     if (to < tov) tov = to;
     long i;
     for (i = from; i <= tov; i += step) {
       block.yield(context, RubyFixnum.newFixnum(runtime, i));
     }
     if (i <= to) {
       block.yield(context, RubyFixnum.newFixnum(runtime, i));
     }
   } else {
     long tov = Long.MIN_VALUE - step;
     if (to > tov) tov = to;
     long i;
     for (i = from; i >= tov; i += step) {
       block.yield(context, RubyFixnum.newFixnum(runtime, i));
     }
     if (i >= to) {
       block.yield(context, RubyFixnum.newFixnum(runtime, i));
     }
   }
 }
Beispiel #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;
  }
Beispiel #5
0
 @JRubyMethod(name = "_id2ref", required = 1, module = true, visibility = Visibility.PRIVATE)
 public static IRubyObject id2ref(IRubyObject recv, IRubyObject id) {
   Ruby runtime = id.getRuntime();
   if (!(id instanceof RubyFixnum)) {
     throw recv.getRuntime().newTypeError(id, recv.getRuntime().getFixnum());
   }
   RubyFixnum idFixnum = (RubyFixnum) id;
   long longId = idFixnum.getLongValue();
   if (longId == 0) {
     return runtime.getFalse();
   } else if (longId == 2) {
     return runtime.getTrue();
   } else if (longId == 4) {
     return runtime.getNil();
   } else if (longId % 2 != 0) {
     // odd
     return runtime.newFixnum((longId - 1) / 2);
   } else {
     if (runtime.isObjectSpaceEnabled()) {
       IRubyObject object = runtime.getObjectSpace().id2ref(longId);
       if (object == null) {
         return runtime.getNil();
       }
       return object;
     } else {
       runtime
           .getWarnings()
           .warn("ObjectSpace is disabled; _id2ref only supports immediates, pass -X+O to enable");
       return runtime.getNil();
     }
   }
 }
Beispiel #6
0
 @Override
 public RubyFixnum id() {
   if ((flags & FALSE_F) == 0) {
     return RubyFixnum.newFixnum(getRuntime(), 2);
   } else {
     return RubyFixnum.zero(getRuntime());
   }
 }
Beispiel #7
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();
 }
Beispiel #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();
 }
Beispiel #9
0
 /** int_succ */
 @JRubyMethod(name = {"succ", "next"})
 public IRubyObject succ(ThreadContext context) {
   if (this instanceof RubyFixnum) {
     return RubyFixnum.newFixnum(context.getRuntime(), getLongValue() + 1L);
   } else {
     return callMethod(context, "+", RubyFixnum.one(context.getRuntime()));
   }
 }
Beispiel #10
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;
   }
 }
Beispiel #11
0
 public WarningGlobalVariable(
     Ruby runtime, String name, RubyInstanceConfig.Verbosity verbosity) {
   super(
       runtime,
       name,
       verbosity == RubyInstanceConfig.Verbosity.NIL
           ? RubyFixnum.newFixnum(runtime, 0)
           : verbosity == RubyInstanceConfig.Verbosity.FALSE
               ? RubyFixnum.newFixnum(runtime, 1)
               : verbosity == RubyInstanceConfig.Verbosity.TRUE
                   ? RubyFixnum.newFixnum(runtime, 2)
                   : runtime.getNil());
 }
Beispiel #12
0
  @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));
  }
Beispiel #13
0
  public static RubyClass createFloatClass(Ruby runtime) {
    RubyClass floatc =
        runtime.defineClass(
            "Float", runtime.getNumeric(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
    runtime.setFloat(floatc);

    floatc.setClassIndex(ClassIndex.FLOAT);
    floatc.setReifiedClass(RubyFloat.class);

    floatc.kindOf = new RubyModule.JavaClassKindOf(RubyFloat.class);

    floatc.getSingletonClass().undefineMethod("new");

    // Java Doubles are 64 bit long:
    floatc.defineConstant("ROUNDS", RubyFixnum.newFixnum(runtime, ROUNDS));
    floatc.defineConstant("RADIX", RubyFixnum.newFixnum(runtime, RADIX));
    floatc.defineConstant("MANT_DIG", RubyFixnum.newFixnum(runtime, MANT_DIG));
    floatc.defineConstant("DIG", RubyFixnum.newFixnum(runtime, DIG));
    // Double.MAX_EXPONENT since Java 1.6
    floatc.defineConstant("MIN_EXP", RubyFixnum.newFixnum(runtime, MIN_EXP));
    // Double.MAX_EXPONENT since Java 1.6
    floatc.defineConstant("MAX_EXP", RubyFixnum.newFixnum(runtime, MAX_EXP));
    floatc.defineConstant("MIN_10_EXP", RubyFixnum.newFixnum(runtime, MIN_10_EXP));
    floatc.defineConstant("MAX_10_EXP", RubyFixnum.newFixnum(runtime, MAX_10_EXP));
    floatc.defineConstant("MIN", RubyFloat.newFloat(runtime, Double.MIN_VALUE));
    floatc.defineConstant("MAX", RubyFloat.newFloat(runtime, Double.MAX_VALUE));
    floatc.defineConstant("EPSILON", RubyFloat.newFloat(runtime, EPSILON));

    floatc.defineConstant("INFINITY", RubyFloat.newFloat(runtime, INFINITY));
    floatc.defineConstant("NAN", RubyFloat.newFloat(runtime, NAN));

    floatc.defineAnnotatedMethods(RubyFloat.class);

    return floatc;
  }
Beispiel #14
0
 private void fixnumStep(ThreadContext context, Ruby runtime, long unit, Block block) {
   long e = ((RubyFixnum) end).getLongValue();
   if (!isExclusive) e++;
   for (long i = ((RubyFixnum) begin).getLongValue(); i < e; i += unit) {
     block.yield(context, RubyFixnum.newFixnum(runtime, i));
   }
 }
Beispiel #15
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);
 }
Beispiel #16
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;
 }
Beispiel #17
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();
 }
Beispiel #18
0
 /** num_abs */
 @JRubyMethod(name = "abs")
 public IRubyObject abs(ThreadContext context) {
   if (callMethod(context, "<", RubyFixnum.zero(getRuntime())).isTrue()) {
     return callMethod(context, "-@");
   }
   return this;
 }
Beispiel #19
0
 /** flo_is_infinite_p */
 @JRubyMethod(name = "infinite?")
 public IRubyObject infinite_p() {
   if (Double.isInfinite(value)) {
     return RubyFixnum.newFixnum(getRuntime(), value < 0 ? -1 : 1);
   }
   return getRuntime().getNil();
 }
Beispiel #20
0
  private static IRubyObject convertToNum(double val, Ruby runtime) {

    if (val >= (double) RubyFixnum.MAX || val < (double) RubyFixnum.MIN) {
      return RubyBignum.newBignum(runtime, val);
    }
    return RubyFixnum.newFixnum(runtime, (long) val);
  }
Beispiel #21
0
 /** match_end */
 @JRubyMethod(name = "end", compat = CompatVersion.RUBY1_8)
 public IRubyObject end(ThreadContext context, IRubyObject index) {
   int i = RubyNumeric.num2int(index);
   Ruby runtime = context.getRuntime();
   int e = endCommon(runtime, i);
   return e < 0 ? runtime.getNil() : RubyFixnum.newFixnum(runtime, e);
 }
Beispiel #22
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());
  }
Beispiel #23
0
  @JRubyMethod(name = "initialize", optional = 2, frame = true, visibility = Visibility.PRIVATE)
  public IRubyObject initialize(IRubyObject[] args, Block unusedBlock) {
    Object modeArgument = null;
    switch (args.length) {
      case 0:
        internal = RubyString.newEmptyString(getRuntime());
        modeArgument = "r+";
        break;
      case 1:
        internal = args[0].convertToString();
        modeArgument = internal.isFrozen() ? "r" : "r+";
        break;
      case 2:
        internal = args[0].convertToString();
        if (args[1] instanceof RubyFixnum) {
          modeArgument = RubyFixnum.fix2long(args[1]);
        } else {
          modeArgument = args[1].convertToString().toString();
        }
        break;
    }

    initializeModes(modeArgument);

    if (modes.isWritable() && internal.isFrozen()) {
      throw getRuntime().newErrnoEACCESError("Permission denied");
    }

    if (modes.isTruncate()) {
      internal.modifyCheck();
      internal.empty();
    }

    return this;
  }
Beispiel #24
0
  /** 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]);
  }
Beispiel #25
0
 /** int_succ */
 @JRubyMethod(name = {"succ", "next"})
 public IRubyObject succ(ThreadContext context) {
   if (this instanceof RubyFixnum) {
     return ((RubyFixnum) this).op_plus_one(context);
   } else {
     return callMethod(context, "+", RubyFixnum.one(context.runtime));
   }
 }
Beispiel #26
0
 /** flo_denominator */
 @JRubyMethod(name = "denominator")
 @Override
 public IRubyObject denominator(ThreadContext context) {
   if (Double.isInfinite(value) || Double.isNaN(value)) {
     return RubyFixnum.one(context.runtime);
   }
   return super.denominator(context);
 }
Beispiel #27
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");
   }
 }
Beispiel #28
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);
    }
  }
Beispiel #29
0
 @JRubyMethod(name = "max", frame = true, compat = CompatVersion.RUBY1_9)
 public IRubyObject max(ThreadContext context, Block block) {
   if (block.isGiven() || isExclusive && !(end instanceof RubyNumeric)) {
     return RuntimeHelpers.invokeSuper(context, this, block);
   } else {
     int c = RubyComparable.cmpint(context, begin.callMethod(context, "<=>", end), begin, end);
     Ruby runtime = context.getRuntime();
     if (isExclusive) {
       if (!(end instanceof RubyInteger))
         throw runtime.newTypeError("cannot exclude non Integer end value");
       if (c == 0) return runtime.getNil();
       if (end instanceof RubyFixnum)
         return RubyFixnum.newFixnum(runtime, ((RubyFixnum) end).getLongValue() - 1);
       return end.callMethod(context, "-", RubyFixnum.one(runtime));
     }
     return end;
   }
 }
Beispiel #30
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};
  }