long ret = (Long) value; return ret >= 0 ? runtime.newFixnum(ret) : RubyBignum.newBignum(runtime, UINT64_COMPLEMENTARY.add(new BigInteger(ret + ""))); case FLOAT: return runtime.newFloat((Float) value);
public static long num2ulong(Ruby runtime, IRubyObject value) { if (value instanceof RubyFloat) { RubyBignum bignum = RubyBignum.newBignum(runtime, ((RubyFloat) value).getDoubleValue()); return RubyBignum.big2ulong(bignum); } else if (value instanceof RubyBignum) { return RubyBignum.big2ulong((RubyBignum) value); } else { return RubyNumeric.num2long(value); } }
private IRubyObject addFixnum(long other) { BigInteger result = value.add(BigInteger.valueOf(other)); if (other > 0 && value.signum() > 0) return new RubyBignum(getRuntime(), result); return bignorm(getRuntime(), result); }
/** rb_big_lshift * */ @JRubyMethod(name = "<<", required = 1) public IRubyObject op_lshift(IRubyObject other) { long shift; boolean neg = false; for (;;) { if (other instanceof RubyFixnum) { shift = ((RubyFixnum)other).getLongValue(); if (shift < 0) { neg = true; shift = -shift; } break; } else if (other instanceof RubyBignum) { RubyBignum otherBignum = (RubyBignum)other; if (otherBignum.value.signum() < 0) { IRubyObject tmp = otherBignum.checkShiftDown(this); if (!tmp.isNil()) return tmp; neg = true; } shift = big2long(otherBignum); break; } other = other.convertToInteger(); } return bignorm(getRuntime(), neg ? value.shiftRight((int)shift) : value.shiftLeft((int)shift)); }
public IRubyObject opMulOther(ThreadContext context, IRubyObject other) { if (other instanceof RubyFloat) { return RubyFloat.newFloat(getRuntime(), big2dbl(this) * ((RubyFloat) other).getDoubleValue()); } return coerceBin(context, "*", other); }
@Override public final IRubyObject op_plus(ThreadContext context, long other) { BigInteger result = value.add(BigInteger.valueOf(other)); if (other > 0 && value.signum() > 0) return new RubyBignum(context.runtime, result); return bignorm(context.runtime, result); }
/** rb_big2ulong * This is here because for C extensions ulong can hold different values without throwing a RangeError */ public static long big2ulong(RubyBignum value) { BigInteger big = value.getValue(); if (big.compareTo(LONG_MIN) <= 0 || big.compareTo(ULONG_MAX) > 0) { throw value.getRuntime().newRangeError("bignum too big to convert into `ulong'"); } return value.getValue().longValue(); }
@JRubyMethod(name = {"concat", "<<"}, compat = RUBY1_9) public RubyString concat19(ThreadContext context, IRubyObject other) { Ruby runtime = context.runtime; if (other instanceof RubyFixnum) { int c = RubyNumeric.num2int(other); if (c < 0) { throw runtime.newRangeError("negative string size (or size too big)"); } return concatNumeric(runtime, c); } else if (other instanceof RubyBignum) { if (((RubyBignum) other).getBigIntegerValue().signum() < 0) { throw runtime.newRangeError("negative string size (or size too big)"); } long c = ((RubyBignum) other).getLongValue(); return concatNumeric(runtime, (int) c); } if (other instanceof RubySymbol) throw runtime.newTypeError("can't convert Symbol into String"); return append19(other); }
public IRubyObject op_pow(ThreadContext context, long other) { // MRI issuses warning here on (RBIGNUM(x)->len * SIZEOF_BDIGITS * yy > 1024*1024) if (((value.bitLength() + 7) / 8) * 4 * Math.abs(other) > 1024 * 1024) { getRuntime().getWarnings().warn(ID.MAY_BE_TOO_BIG, "in a**b, b may be too big"); } if (other >= 0) { return bignorm(getRuntime(), value.pow((int) other)); // num2int is also implemented } else { return RubyFloat.newFloat(getRuntime(), Math.pow(big2dbl(this), (double)other)); } }
/** rb_big_plus * */ @JRubyMethod(name = "+", required = 1) public IRubyObject op_plus(ThreadContext context, IRubyObject other) { if (other instanceof RubyFixnum) { return addFixnum(((RubyFixnum)other).getLongValue()); } else if (other instanceof RubyBignum) { return addBignum(((RubyBignum)other).value); } else if (other instanceof RubyFloat) { return addFloat((RubyFloat)other); } return addOther(context, other); }
/** rb_big_plus * */ @Override public IRubyObject op_plus(ThreadContext context, IRubyObject other) { if (other instanceof RubyFixnum) { return op_plus(context, ((RubyFixnum) other).getLongValue()); } if (other instanceof RubyBignum) { return op_plus(context, ((RubyBignum) other).value); } if (other instanceof RubyFloat) { return addFloat((RubyFloat) other); } return addOther(context, other); }
/** rb_big_rshift * */ @Override public IRubyObject op_rshift(ThreadContext context, IRubyObject other) { long shift; for (;;) { if (other instanceof RubyFixnum) { shift = ((RubyFixnum) other).getLongValue(); break; } else if (other instanceof RubyBignum) { RubyBignum otherBignum = (RubyBignum) other; if (otherBignum.value.signum() >= 0) { IRubyObject tmp = otherBignum.checkShiftDown(context, this); if (tmp != null) return tmp; } shift = big2long(otherBignum); break; } other = other.convertToInteger(); } return op_rshift(context, shift); }
/** rb_big_lshift * */ @Override public IRubyObject op_lshift(ThreadContext context, IRubyObject other) { long shift; for (;;) { if (other instanceof RubyFixnum) { shift = ((RubyFixnum) other).getLongValue(); break; } else if (other instanceof RubyBignum) { RubyBignum otherBignum = (RubyBignum) other; if (otherBignum.value.signum() < 0) { IRubyObject tmp = otherBignum.checkShiftDown(context, this); if (tmp != null) return tmp; } shift = big2long(otherBignum); break; } other = other.convertToInteger(); } return op_lshift(context, shift); }
public static long other2u64(IRubyObject parameter) { if (parameter instanceof RubyBignum) { return ((RubyBignum) parameter).getValue().longValue(); } else { return other2long(parameter); } }
final RubyFloat fdivDouble(ThreadContext context, RubyBignum y) { double dx = getDoubleValue(); double dy = RubyBignum.big2dbl(y); if (Double.isInfinite(dx) || Double.isInfinite(dy)) { return (RubyFloat) fdivInt(context, y); } return context.runtime.newFloat(dx / dy); }
@Override public int getIntValue() { return (int)big2long(this); }
@Override public RubyString to_s(IRubyObject arg0) { int base = num2int(arg0); if (base < 2 || base > 36) { throw getRuntime().newArgumentError("illegal radix " + base); } return RubyString.newUSASCIIString(getRuntime(), getValue().toString(base)); }
/** rb_big2dbl * */ public static double big2dbl(RubyBignum value) { BigInteger big = value.getValue(); double dbl = convertToDouble(big); if (dbl == Double.NEGATIVE_INFINITY || dbl == Double.POSITIVE_INFINITY) { value.getRuntime().getWarnings().warn(ID.BIGNUM_FROM_FLOAT_RANGE, "Bignum out of Float range"); } return dbl; }
@Override public IRubyObject op_mod(ThreadContext context, long other) { if (other == 0) throw context.runtime.newZeroDivisionError(); BigInteger result = value.mod(long2big(other < 0 ? -other : other)); if (other < 0 && result.signum() != 0) result = long2big(other).add(result); return bignorm(context.runtime, result); }
@Override public double getDoubleValue() { return big2dbl(this); }