Skip to content
Merged
Changes from all commits
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
86 changes: 51 additions & 35 deletions core/src/main/java/org/jruby/RubyFloat.java
Original file line number Diff line number Diff line change
Expand Up @@ -253,40 +253,15 @@ public static IRubyObject induced_from(ThreadContext context, IRubyObject recv,
@JRubyMethod(name = {"to_s", "inspect"})
@Override
public IRubyObject to_s() {
final Ruby runtime = metaClass.runtime;
if (Double.isInfinite(value)) {
return RubyString.newString(runtime, value < 0 ? "-Infinity" : "Infinity");
}
if (Double.isNaN(value)) {
return RubyString.newString(runtime, "NaN");
}

ByteList buf = new ByteList();
// Under 1.9, use full-precision float formatting (JRUBY-4846).
// Double-precision can represent around 16 decimal digits;
// we use 20 to ensure full representation.
Sprintf.sprintf(buf, Locale.US, "%#.20g", this);
int e = buf.indexOf('e');
if (e == -1) e = buf.getRealSize();
ASCIIEncoding ascii = ASCIIEncoding.INSTANCE;

if (!ascii.isDigit(buf.get(e - 1))) {
buf.setRealSize(0);
Sprintf.sprintf(buf, Locale.US, "%#.14e", this);
e = buf.indexOf('e');
if (e == -1) e = buf.getRealSize();
}

int p = e;
while (buf.get(p - 1) == '0' && ascii.isDigit(buf.get(p - 2))) p--;
System.arraycopy(buf.getUnsafeBytes(), e, buf.getUnsafeBytes(), p, buf.getRealSize() - e);
buf.setRealSize(p + buf.getRealSize() - e);

buf.setEncoding(USASCIIEncoding.INSTANCE);

return runtime.newString(buf);
ByteList buf = new ByteList(24);
formatFloat(this, buf);
return RubyString.newString(getRuntime(), buf);
}

public static final ByteList POSITIVE_INFINITY_TO_S_BYTELIST = new ByteList(ByteList.plain("Infinity"), USASCIIEncoding.INSTANCE, false);
public static final ByteList NEGATIVE_INFINITY_TO_S_BYTELIST = new ByteList(ByteList.plain("-Infinity"), USASCIIEncoding.INSTANCE, false);
public static final ByteList NAN_TO_S_BYTELIST = new ByteList(ByteList.plain("NaN"), USASCIIEncoding.INSTANCE, false);

/** flo_coerce
*
*/
Expand Down Expand Up @@ -846,8 +821,8 @@ public IRubyObject rationalize(ThreadContext context, IRubyObject[] args) {
RubyInteger den;

RubyInteger two_times_f = (RubyInteger) rf.op_mul(context, 2);
den = (RubyInteger) one.op_lshift(context, RubyFixnum.one(runtime).op_minus(context, n));
den = (RubyInteger) one.op_lshift(context, one.op_minus(context, n));

a = RubyRational.newRationalRaw(runtime, two_times_f.op_minus(context, 1), den);
b = RubyRational.newRationalRaw(runtime, two_times_f.op_plus(context, 1), den);
}
Expand Down Expand Up @@ -1215,7 +1190,48 @@ private ByteList marshalDump() {
return byteList;
}

public static void marshalTo(RubyFloat aFloat, MarshalStream output) throws java.io.IOException {
public static ByteList formatFloat(RubyFloat self, ByteList buf) {
buf.setRealSize(0);

double value = self.value;

if (Double.isInfinite(value)) {
buf.append(value < 0
? NEGATIVE_INFINITY_TO_S_BYTELIST
: POSITIVE_INFINITY_TO_S_BYTELIST);
buf.setEncoding(USASCIIEncoding.INSTANCE);
return buf;
}

if (Double.isNaN(value)) {
buf.append(NAN_TO_S_BYTELIST);
buf.setEncoding(USASCIIEncoding.INSTANCE);
return buf;
}

Sprintf.sprintf(buf, Locale.US, "%#.20g", self);

int e = buf.indexOf('e');
if (e == -1) e = buf.getRealSize();
ASCIIEncoding ascii = ASCIIEncoding.INSTANCE;

if (!ascii.isDigit(buf.get(e - 1))) {
buf.setRealSize(0);
Sprintf.sprintf(buf, Locale.US, "%#.14e", self);
e = buf.indexOf('e');
if (e == -1) e = buf.getRealSize();
}

int p = e;
while (buf.get(p - 1) == '0' && ascii.isDigit(buf.get(p - 2))) p--;
System.arraycopy(buf.getUnsafeBytes(), e, buf.getUnsafeBytes(), p, buf.getRealSize() - e);
buf.setRealSize(p + buf.getRealSize() - e);

buf.setEncoding(USASCIIEncoding.INSTANCE);
return buf;
}

public static void marshalTo(RubyFloat aFloat, org.jruby.runtime.marshal.MarshalStream output) throws java.io.IOException {
output.registerLinkTarget(aFloat);
output.writeString(aFloat.marshalDump());
}
Expand Down
Loading