diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/DoubleVectorPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/DoubleVectorPrinter.java index b86ea1637eb4b486e0fe268acbe2ce7dde608e54..1c3df1c59f40dc33de4b909f935aa54be4febb28 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/DoubleVectorPrinter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/DoubleVectorPrinter.java @@ -214,7 +214,7 @@ public final class DoubleVectorPrinter extends VectorPrinter<RAbstractDoubleVect return new DoubleVectorMetrics(w, d, e); } - private static final int DBL_DIG = 15; + @SuppressWarnings("unused") private static final int DBL_DIG = 15; private static final double[] tbl = { 1e-1, @@ -282,13 +282,14 @@ public final class DoubleVectorPrinter extends VectorPrinter<RAbstractDoubleVect r = x; } - if (digits >= DBL_DIG + 1) { - // TODO: - // format_via_sprintf(r, pp.getDigits(), kpower, nsig); - roundingwidens = false; - // return; - throw new UnsupportedOperationException(); - } + // we ignore this special case for the time being: + // if (digits >= DBL_DIG + 1) { + // // TODO: + // // format_via_sprintf(r, pp.getDigits(), kpower, nsig); + // roundingwidens = false; + // // return; + // throw new UnsupportedOperationException(); + // } kp = (int) Math.floor(Math.log10(r)) - digits + 1; // r = |x|; // 10^(kp + digits - 1) <= r @@ -434,9 +435,12 @@ public final class DoubleVectorPrinter extends VectorPrinter<RAbstractDoubleVect if (x == 0) { log10 = 0; } else { - if (x < 1e-300) { + if (x < 1e-200) { + // if we're close to the smallest double numbers, the loop that calculates + // digits will produce errors shifted = true; x *= 1e100; + assert Math.abs(Math.log10(x)) >= 100 : "should not shift into 2-digit exponents"; } log10 = (int) Math.log10(x); if (DECIMAL_WEIGHTS[log10 + DECIMAL_SHIFT] > x) { @@ -553,7 +557,7 @@ public final class DoubleVectorPrinter extends VectorPrinter<RAbstractDoubleVect private static double appendDigit(double x, int digit, StringBuilder str) { int c = (int) (x / DECIMAL_WEIGHTS[digit + DECIMAL_SHIFT]); - assert c >= 0 && c <= 9; + assert c >= 0 && c <= 9 : c; str.append((char) ('0' + c)); return x - DECIMAL_VALUES[digit + DECIMAL_SHIFT][c]; } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test index 6a51fbf92da9510b58391a9f04ddfddd074e79d9..f61ac6982f9debc18ca4f4ebb99fa3eddb9f84c2 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test @@ -26383,6 +26383,10 @@ Error in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3L, : #format(1.6011095, digits=7) [1] "1.601109" +##com.oracle.truffle.r.test.builtins.TestBuiltin_format.testFormat# +#format(2147483647 / 1.7976931348623157E308, digits =15) +[1] "1.19457743112785e-299" + ##com.oracle.truffle.r.test.builtins.TestBuiltin_format.testFormat# #format(4.125e-04, digits=3) [1] "0.000412" @@ -26424,6 +26428,10 @@ Error in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3L, : #format(c(9.99951, 13.1), digits=4) [1] "10.0" "13.1" +##com.oracle.truffle.r.test.builtins.TestBuiltin_format.testFormat# +#substr(format(2147483647 / 1.7976931348623157E308, digits =22), 1,16+1) +[1] "1.194577431127851" + ##com.oracle.truffle.r.test.builtins.TestBuiltin_format.testformat1#Output.IgnoreErrorMessage# #argv <- list(structure(c(0, 72.7, 56.4, 72.7, 0, 63.3, 56.4, 63.3, 0), .Dim = c(3L, 3L), .Dimnames = list(c('Girth', 'Height', 'Volume'), c('Girth', 'Height', 'Volume'))), FALSE, 7L, 0L, NULL, 3L, TRUE, NA, "."); .Internal(format(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]], argv[[8]], argv[[9]], , argv[[9]])) Error in .Internal(format(argv[[1]], argv[[2]], argv[[3]], argv[[4]], : diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_format.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_format.java index a05621fb9d16772182e1bc1ba1712193235e1935..a4a0dc9e2bf3d8a203cf2fe78b690aa53b21a596 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_format.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_format.java @@ -309,5 +309,8 @@ public class TestBuiltin_format extends TestBase { assertEval("format(4.135e-04, digits=3)"); assertEval("format(9.999999999995, digits=13); format(9.999999999995, digits=11)"); assertEval("format(9.999999995, digits=10)"); + assertEval("format(2147483647 / 1.7976931348623157E308, digits =15)"); + // only the first 16 decimal digits (53 bits) contain useful information (+ decimal point) + assertEval("substr(format(2147483647 / 1.7976931348623157E308, digits =22), 1,16+1)"); } }