Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: db484cc30a54
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 1acb1f0cd9a5
Choose a head ref
  • 2 commits
  • 4 files changed
  • 2 contributors

Commits on Apr 6, 2015

  1. Copy the full SHA
    b9d7b7f View commit details
  2. Merge pull request #2806 from bjfish/truffle_float_round

    [Truffle] Move Float#round to float.rb
    chrisseaton committed Apr 6, 2015
    Copy the full SHA
    1acb1f0 View commit details
9 changes: 0 additions & 9 deletions spec/truffle/tags/core/float/round_tags.txt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@
import org.jruby.truffle.runtime.DebugOperations;
import org.jruby.truffle.runtime.RubyCallStack;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.UndefinedPlaceholder;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.*;

@@ -729,7 +730,7 @@ public boolean nan(double value) {

}

@CoreMethod(names = "round")
@CoreMethod(names = "round", optional = 1)
public abstract static class RoundNode extends CoreMethodNode {

@Child private FixnumOrBignumNode fixnumOrBignum;
@@ -748,7 +749,7 @@ public RoundNode(RoundNode prev) {
}

@Specialization
public Object round(double n) {
public Object round(double n, UndefinedPlaceholder undefinedPlaceholder) {
// Algorithm copied from JRuby - not shared as we want to branch profile it

if (Double.isInfinite(n)) {
@@ -784,6 +785,11 @@ public Object round(double n) {
return fixnumOrBignum.fixnumOrBignum(f);
}

@Specialization(guards = "!isUndefinedPlaceholder(arguments[1])")
public Object round(VirtualFrame frame, double n, Object ndigits) {
return ruby(frame, "round_internal(ndigits)", "ndigits", ndigits);
}

}

@CoreMethod(names = { "to_i", "to_int", "truncate" })
Original file line number Diff line number Diff line change
@@ -9,9 +9,13 @@
*/
package org.jruby.truffle.nodes.rubinius;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.BranchProfile;
import org.jruby.truffle.nodes.core.FixnumOrBignumNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyArray;

import java.util.Locale;
@@ -86,4 +90,61 @@ public boolean floatNegative(double value) {

}

@RubiniusPrimitive(name = "float_round")
public static abstract class FloatRoundPrimitiveNode extends RubiniusPrimitiveNode {

@Child private FixnumOrBignumNode fixnumOrBignum;

private final BranchProfile greaterZero = BranchProfile.create();
private final BranchProfile lessZero = BranchProfile.create();

public FloatRoundPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
fixnumOrBignum = new FixnumOrBignumNode(context, sourceSection);
}

public FloatRoundPrimitiveNode(FloatRoundPrimitiveNode prev) {
super(prev);
fixnumOrBignum = prev.fixnumOrBignum;
}

@Specialization
public Object round(double n) {
// Algorithm copied from JRuby - not shared as we want to branch profile it

if (Double.isInfinite(n)) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().floatDomainError("Infinity", this));
}

if (Double.isNaN(n)) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().floatDomainError("NaN", this));
}

double f = n;

if (f > 0.0) {
greaterZero.enter();

f = Math.floor(f);

if (n - f >= 0.5) {
f += 1.0;
}
} else if (f < 0.0) {
lessZero.enter();

f = Math.ceil(f);

if (f - n >= 0.5) {
f -= 1.0;
}
}

return fixnumOrBignum.fixnumOrBignum(f);
}

}

}
26 changes: 26 additions & 0 deletions truffle/src/main/ruby/core/rubinius/common/float.rb
Original file line number Diff line number Diff line change
@@ -97,6 +97,32 @@ def rationalize(eps=undefined)
end
end

# MODIFIED name to call from java
def round_internal(ndigits=0)
ndigits = Rubinius::Type.coerce_to(ndigits, Integer, :to_int)

if ndigits == 0
return Rubinius.invoke_primitive :float_round, self
elsif ndigits < 0
return truncate.round ndigits
end

return self if infinite? or nan?

_, exp = Math.frexp(self)

if ndigits >= (Float::DIG + 2) - (exp > 0 ? exp / 4 : exp / 3 - 1)
return self
end

if ndigits < -(exp > 0 ? exp / 3 + 1 : exp / 4)
return 0.0
end

f = 10**ndigits
Rubinius.invoke_primitive(:float_round, self * f) / f.to_f
end

def dtoa
Rubinius.primitive :float_dtoa
raise PrimitiveFailure, "Fload#dtoa primitive failed"