Skip to content

Commit cf94613

Browse files
evaniainbrooksheadius
authored andcommitted
Output formatting differences between jRuby 10.0.0.1 and Ruby 3.4 when converting Float to JSON
1 parent f33d4ae commit cf94613

1 file changed

Lines changed: 47 additions & 35 deletions

File tree

core/src/main/java/org/jruby/RubyFloat.java

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -253,38 +253,9 @@ public static IRubyObject induced_from(ThreadContext context, IRubyObject recv,
253253
@JRubyMethod(name = {"to_s", "inspect"})
254254
@Override
255255
public IRubyObject to_s() {
256-
final Ruby runtime = metaClass.runtime;
257-
if (Double.isInfinite(value)) {
258-
return RubyString.newStringShared(runtime, value < 0 ? NEGATIVE_INFINITY_TO_S_BYTELIST : POSITIVE_INFINITY_TO_S_BYTELIST);
259-
}
260-
if (Double.isNaN(value)) {
261-
return RubyString.newStringShared(runtime, NAN_TO_S_BYTELIST);
262-
}
263-
264-
ByteList buf = new ByteList();
265-
// Under 1.9, use full-precision float formatting (JRUBY-4846).
266-
// Double-precision can represent around 16 decimal digits;
267-
// we use 20 to ensure full representation.
268-
Sprintf.sprintf(buf, Locale.US, "%#.20g", this);
269-
int e = buf.indexOf('e');
270-
if (e == -1) e = buf.getRealSize();
271-
ASCIIEncoding ascii = ASCIIEncoding.INSTANCE;
272-
273-
if (!ascii.isDigit(buf.get(e - 1))) {
274-
buf.setRealSize(0);
275-
Sprintf.sprintf(buf, Locale.US, "%#.14e", this);
276-
e = buf.indexOf('e');
277-
if (e == -1) e = buf.getRealSize();
278-
}
279-
280-
int p = e;
281-
while (buf.get(p - 1) == '0' && ascii.isDigit(buf.get(p - 2))) p--;
282-
System.arraycopy(buf.getUnsafeBytes(), e, buf.getUnsafeBytes(), p, buf.getRealSize() - e);
283-
buf.setRealSize(p + buf.getRealSize() - e);
284-
285-
buf.setEncoding(USASCIIEncoding.INSTANCE);
286-
287-
return runtime.newString(buf);
256+
ByteList buf = new ByteList(24);
257+
formatFloat(this, buf);
258+
return RubyString.newString(getRuntime(), buf);
288259
}
289260

290261
public static final ByteList POSITIVE_INFINITY_TO_S_BYTELIST = new ByteList(ByteList.plain("Infinity"), USASCIIEncoding.INSTANCE, false);
@@ -850,8 +821,8 @@ public IRubyObject rationalize(ThreadContext context, IRubyObject[] args) {
850821
RubyInteger den;
851822

852823
RubyInteger two_times_f = (RubyInteger) rf.op_mul(context, 2);
853-
den = (RubyInteger) one.op_lshift(context, RubyFixnum.one(runtime).op_minus(context, n));
854-
824+
den = (RubyInteger) one.op_lshift(context, one.op_minus(context, n));
825+
855826
a = RubyRational.newRationalRaw(runtime, two_times_f.op_minus(context, 1), den);
856827
b = RubyRational.newRationalRaw(runtime, two_times_f.op_plus(context, 1), den);
857828
}
@@ -1219,7 +1190,48 @@ private ByteList marshalDump() {
12191190
return byteList;
12201191
}
12211192

1222-
public static void marshalTo(RubyFloat aFloat, MarshalStream output) throws java.io.IOException {
1193+
public static ByteList formatFloat(RubyFloat self, ByteList buf) {
1194+
buf.setRealSize(0);
1195+
1196+
double value = self.value;
1197+
1198+
if (Double.isInfinite(value)) {
1199+
buf.append(value < 0
1200+
? NEGATIVE_INFINITY_TO_S_BYTELIST
1201+
: POSITIVE_INFINITY_TO_S_BYTELIST);
1202+
buf.setEncoding(USASCIIEncoding.INSTANCE);
1203+
return buf;
1204+
}
1205+
1206+
if (Double.isNaN(value)) {
1207+
buf.append(NAN_TO_S_BYTELIST);
1208+
buf.setEncoding(USASCIIEncoding.INSTANCE);
1209+
return buf;
1210+
}
1211+
1212+
Sprintf.sprintf(buf, Locale.US, "%#.20g", self);
1213+
1214+
int e = buf.indexOf('e');
1215+
if (e == -1) e = buf.getRealSize();
1216+
ASCIIEncoding ascii = ASCIIEncoding.INSTANCE;
1217+
1218+
if (!ascii.isDigit(buf.get(e - 1))) {
1219+
buf.setRealSize(0);
1220+
Sprintf.sprintf(buf, Locale.US, "%#.14e", self);
1221+
e = buf.indexOf('e');
1222+
if (e == -1) e = buf.getRealSize();
1223+
}
1224+
1225+
int p = e;
1226+
while (buf.get(p - 1) == '0' && ascii.isDigit(buf.get(p - 2))) p--;
1227+
System.arraycopy(buf.getUnsafeBytes(), e, buf.getUnsafeBytes(), p, buf.getRealSize() - e);
1228+
buf.setRealSize(p + buf.getRealSize() - e);
1229+
1230+
buf.setEncoding(USASCIIEncoding.INSTANCE);
1231+
return buf;
1232+
}
1233+
1234+
public static void marshalTo(RubyFloat aFloat, org.jruby.runtime.marshal.MarshalStream output) throws java.io.IOException {
12231235
output.registerLinkTarget(aFloat);
12241236
output.writeString(aFloat.marshalDump());
12251237
}

0 commit comments

Comments
 (0)