Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ruby 2.4] Fixes for Integer#digits in PR #4375 #4490

Merged
merged 4 commits into from
Feb 24, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions core/src/main/java/org/jruby/RubyBignum.java
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,54 @@ public static BigInteger long2big(long arg) {
* ================
*/

/** rb_big_digits
*
*/
@Override
public RubyArray digits(ThreadContext context, IRubyObject base) {
BigInteger self = (this).getValue();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could just access the field here, or at least call it without the parens. I assume this is just a mistake converting the RubyFixnum-only logic.

if (self.compareTo(new BigInteger("0")) == -1) {
throw context.getRuntime().newMathDomainError("out of domain");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throw context.runtime into a local variable at the top and reuse it, in the style of other methods.

}
if (!(base instanceof RubyInteger)) {
try {
base = base.convertToInteger();
} catch (ClassCastException e) {
String cname = base.getMetaClass().getRealClass().getName();
throw context.getRuntime().newTypeError("wrong argument type " + cname + " (expected Integer)");
}
}

BigInteger bigBase;
if (base instanceof RubyBignum) {
bigBase = ((RubyBignum) base).getValue();
} else {
bigBase = long2big( ((RubyFixnum) base).getLongValue() );
}

if (bigBase.compareTo(BigInteger.ZERO) == -1) {
throw context.getRuntime().newArgumentError("negative radix");
}
if (bigBase.compareTo(new BigInteger("2")) == -1) {
throw context.getRuntime().newArgumentError("invalid radix: " + bigBase);
}

RubyArray res = RubyArray.newArray(context.runtime, 0);

if (self.compareTo(new BigInteger("0")) == 0) {
res.append(RubyFixnum.newFixnum(context.getRuntime(), 0));
return res;
}

while (self.compareTo(BigInteger.ZERO) > 0) {
BigInteger q = self.mod(bigBase);
res.append(RubyBignum.newBignum(context.getRuntime(), q));
self = self.divide(bigBase);
}

return res;
}

/** rb_big_to_s
*
*/
Expand Down
47 changes: 47 additions & 0 deletions core/src/main/java/org/jruby/RubyFixnum.java
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,53 @@ public IRubyObject times(ThreadContext context, Block block) {
return RubyEnumerator.enumeratorizeWithSize(context, this, "times", timesSizeFn(context.runtime));
}

/** rb_fix_digits
*
*/
@Override
public RubyArray digits(ThreadContext context, IRubyObject base) {

long self = ((RubyFixnum)this).getLongValue();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not necessary...this is already known to be RubyFixnum.

if (self < 0) {
throw context.getRuntime().newMathDomainError("out of domain");
}
if (!(base instanceof RubyInteger)) {
try {
base = base.convertToInteger();
} catch (ClassCastException e) {
String cname = base.getMetaClass().getRealClass().getName();
throw context.getRuntime().newTypeError("wrong argument type " + cname + " (expected Integer)");
}
}
if (base instanceof RubyBignum){
return RubyArray
.newArray(context.runtime, 1)
.append(RubyFixnum.newFixnum(context.getRuntime(), self));
}
long longBase = ((RubyFixnum)base).getLongValue();
if (longBase < 0) {
throw context.getRuntime().newArgumentError("negative radix");
}
if (longBase < 2) {
throw context.getRuntime().newArgumentError("invalid radix: " + longBase);
}

RubyArray res = RubyArray.newArray(context.runtime, 0);

if (self == 0) {
res.append(RubyFixnum.newFixnum(context.getRuntime(), 0));
return res;
}

while (self > 0) {
long q = self % longBase;
res.append(RubyFixnum.newFixnum(context.getRuntime(), q));
self /= longBase;
}

return res;
}

/** fix_to_s
*
*/
Expand Down
38 changes: 1 addition & 37 deletions core/src/main/java/org/jruby/RubyInteger.java
Original file line number Diff line number Diff line change
Expand Up @@ -521,43 +521,7 @@ public RubyArray digits(ThreadContext context) {
}

@JRubyMethod(name = "digits")
public RubyArray digits(ThreadContext context, IRubyObject base) {
long self = ((RubyFixnum)this).getLongValue();
if (self < 0) {
throw context.getRuntime().newMathDomainError("out of domain");
}
if (!(base instanceof RubyInteger)) {
try {
base = base.convertToInteger();
} catch (ClassCastException e) {
String cname = base.getMetaClass().getRealClass().getName();
throw context.getRuntime().newTypeError("wrong argument type " + cname + " (expected Integer)");
}
}

long longBase = ((RubyFixnum)base).getLongValue();
if (longBase < 0) {
throw context.getRuntime().newArgumentError("negative radix");
}
if (longBase < 2) {
throw context.getRuntime().newArgumentError("invalid radix: " + longBase);
}

RubyArray res = RubyArray.newArray(context.runtime, 0);

if (self == 0) {
res.append(RubyFixnum.newFixnum(context.getRuntime(), 0));
return res;
}

while (self > 0) {
long q = self % longBase;
res.append(RubyFixnum.newFixnum(context.getRuntime(), q));
self /= longBase;
}

return res;
}
public abstract RubyArray digits(ThreadContext context, IRubyObject base);

@Override
@JRubyMethod(name = "numerator")
Expand Down