diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ComplexVectorPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ComplexVectorPrinter.java
index 635ec096266e654196e0ba316bf4b1b073197384..1416ca77c41feada5d35aee74e388cf51f641710 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ComplexVectorPrinter.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ComplexVectorPrinter.java
@@ -427,27 +427,14 @@ public final class ComplexVectorPrinter extends VectorPrinter<RAbstractComplexVe
 
     @TruffleBoundary
     private static String encodeComplex(RComplex x, int wr, int dr, int er, int wi, int di, int ei, char cdec, int digits, String naString) {
-        String buff;
-        String im;
-        String re;
-        boolean flagNegIm = false;
-        RComplex y;
-
-        double xr = x.getRealPart();
-        double xi = x.getImaginaryPart();
-
         /* IEEE allows signed zeros; strip these here */
-        if (xr == 0.0) {
-            xr = 0.0;
-        }
-        if (xi == 0.0) {
-            xi = 0.0;
-        }
+        double xr = RRuntime.normalizeZero(x.getRealPart());
+        double xi = RRuntime.normalizeZero(x.getImaginaryPart());
 
         if (RRuntime.isNA(xr) || RRuntime.isNA(xi)) {
             int g = Math.min(wr + wi + 2, (NB - 1));
             String fmt = "%" + Utils.asBlankArg(g) + "s";
-            buff = Utils.snprintf(NB,
+            return Utils.snprintf(NB,
                             fmt, /* was "%*s%*s", R_print.gap, "", */
                             naString);
         } else {
@@ -456,24 +443,25 @@ public final class ComplexVectorPrinter extends VectorPrinter<RAbstractComplexVe
              * get strange trailing zeros. But we do want to avoid printing small exponentials that
              * are probably garbage.
              */
-            y = zprecr(x, digits);
+            RComplex y = zprecr(x, digits);
+            String re;
             if (y.getRealPart() == 0.) {
                 re = DoubleVectorPrinter.encodeReal(y.getRealPart(), wr, dr, er, cdec, naString);
             } else {
                 re = DoubleVectorPrinter.encodeReal(xr, wr, dr, er, cdec, naString);
             }
-            flagNegIm = xi < 0;
+            boolean flagNegIm = xi < 0;
             if (flagNegIm) {
                 xi = -xi;
             }
+            String im;
             if (y.getImaginaryPart() == 0.) {
                 im = DoubleVectorPrinter.encodeReal(y.getImaginaryPart(), wi, di, ei, cdec, naString);
             } else {
                 im = DoubleVectorPrinter.encodeReal(xi, wi, di, ei, cdec, naString);
             }
-            buff = snprintf(NB, "%s%s%si", re, flagNegIm ? "-" : "+", im);
+            return snprintf(NB, "%s%s%si", re, flagNegIm ? "-" : "+", im);
         }
-        return buff;
     }
 
     public static String[] format(RAbstractComplexVector value, boolean trim, int nsmall, int width, char decimalMark, PrintParameters pp) {
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 9ee413f6e6f9a50696f92847f6361c4628c1038d..d3ebedd8fe3c597764ce73f4e78956df9d057640 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
@@ -11,11 +11,7 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base.printer;
 
-import static com.oracle.truffle.r.nodes.builtin.base.printer.Utils.snprintf;
-
 import java.io.IOException;
-import java.math.RoundingMode;
-import java.text.DecimalFormat;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.r.runtime.RRuntime;
@@ -312,9 +308,9 @@ public final class DoubleVectorPrinter extends VectorPrinter<RAbstractDoubleVect
                  * assumption that R_dec_min_exponent+303 is in range. Representation of 1e+303 has
                  * low error.
                  */
-                rPrec = (rPrec * 1e+303) / Math.pow(10, kp + 303);
+                rPrec = (rPrec * 1e+303) / DECIMAL_WEIGHTS[kp + 303 + DECIMAL_SHIFT];
             } else {
-                rPrec /= Math.pow(10, kp);
+                rPrec /= DECIMAL_WEIGHTS[kp + DECIMAL_SHIFT];
             }
             if (rPrec < tbl[digits]) {
                 rPrec *= 10.0;
@@ -354,7 +350,6 @@ public final class DoubleVectorPrinter extends VectorPrinter<RAbstractDoubleVect
             double fuzz = 0.5 / tbl[1 + rgt];
             // kpower can be bigger than the table.
             roundingwidens = kpower > 0 && kpower <= KP_MAX && r < tbl[kpower + 1] - fuzz;
-
         }
 
         return new ScientificDouble(sgn, kpower, nsig, roundingwidens);
@@ -386,14 +381,27 @@ public final class DoubleVectorPrinter extends VectorPrinter<RAbstractDoubleVect
         return encodeReal(x, dm.maxWidth, dm.d, dm.e, '.', pp);
     }
 
-    // caching some commonly used formats
-    private static final DecimalFormat[] CACHED_FORMATS = new DecimalFormat[32];
+    private static final int DECIMAL_SHIFT = 350;
+    private static final double[][] DECIMAL_VALUES = new double[700][10];
+    private static final double[] DECIMAL_WEIGHTS = new double[700];
+
+    static {
+        for (int i = 0; i < DECIMAL_WEIGHTS.length; i++) {
+            DECIMAL_WEIGHTS[i] = Math.pow(10, i - DECIMAL_SHIFT);
+        }
+        for (int i = 0; i < DECIMAL_VALUES.length; i++) {
+            for (int i2 = 0; i2 < 10; i2++) {
+                DECIMAL_VALUES[i][i2] = Math.pow(10, i - DECIMAL_SHIFT) * i2;
+            }
+        }
+    }
 
     @TruffleBoundary
     static String encodeReal(double initialX, int w, int d, int e, char cdec, String naString) {
         /* IEEE allows signed zeros (yuck!) */
         double x = RRuntime.normalizeZero(initialX);
 
+        StringBuilder str = new StringBuilder(w);
         if (!RRuntime.isFinite(x)) {
             String id;
             if (RRuntime.isNA(x)) {
@@ -403,49 +411,120 @@ public final class DoubleVectorPrinter extends VectorPrinter<RAbstractDoubleVect
             } else {
                 id = x > 0 ? "Inf" : "-Inf";
             }
-            return prependBlanks(w, id);
-        } else if (e != 0) {
-            String fmt = String.format((d != 0) ? "%%#%d.%de" : "%%%d.%de", Math.min(w, (NB - 1)), d);
-            String result;
-            if (Math.abs(x) < 1e-300 && Math.abs(x) >= Double.MIN_VALUE) {
-                // work around java formatting bug for small numbers like 1.53160350210786e-322
-                result = snprintf(NB, fmt, x * 1e100);
-                StringBuilder str = new StringBuilder(result);
-                assert str.charAt(str.length() - 3) == '2';
-                str.setCharAt(str.length() - 3, '3');
-                result = str.toString();
-            } else {
-                result = snprintf(NB, fmt, x);
+            int blanks = w - id.length();
+            for (int i = 0; i < blanks; i++) {
+                str.append(' ');
             }
-            return result.replace('.', cdec);
-        } else { /* e = 0 */
-            DecimalFormat df = null;
-            if (d < CACHED_FORMATS.length) {
-                df = CACHED_FORMATS[d];
+            str.append(id);
+        } else {
+            boolean negated = x < 0;
+            if (negated) {
+                x = -x;
             }
-            if (df == null) {
-                df = new DecimalFormat("#.#");
-                df.setRoundingMode(RoundingMode.HALF_EVEN);
-                df.setDecimalSeparatorAlwaysShown(false);
-                df.setMinimumFractionDigits(d);
-                df.setMaximumFractionDigits(d);
-                if (d < CACHED_FORMATS.length) {
-                    CACHED_FORMATS[d] = df;
+            if (e != 0) {
+
+                boolean shifted = false;
+                int log10;
+                int adjustedE = e;
+                if (x == 0) {
+                    log10 = 0;
+                } else {
+                    if (x < 1e-300) {
+                        shifted = true;
+                        x *= 1e100;
+                    }
+                    log10 = (int) Math.log10(x);
+                    if (DECIMAL_WEIGHTS[log10 + DECIMAL_SHIFT] > x) {
+                        // log10 behaves differently for < 1.0
+                        log10--;
+                    }
+                    if (log10 <= -100 || log10 >= 100) {
+                        adjustedE = 3;
+                    }
+                }
+                int blanks = w // target width
+                                - (negated ? 1 : 0) // "-"
+                                - 1 // digits before "."
+                                - (d > 0 ? 1 : 0)  // "."
+                                - d // digits after "."
+                                - 1 // "e"
+                                - 1 // "+/-" for exponent
+                                - Math.max(2, adjustedE); // digits for exponent
+                for (int i = 0; i < blanks; i++) {
+                    str.append(' ');
+                }
+                // round towards next digit instead of truncating
+                double rounded = x + DECIMAL_VALUES[log10 - d - 1 + DECIMAL_SHIFT][5];
+                if (Double.isFinite(rounded)) {
+                    x = rounded;
+                    // the rounding might have modified the exponent
+                    if (DECIMAL_WEIGHTS[log10 + 1 + DECIMAL_SHIFT] <= x) {
+                        log10++;
+                    }
+                }
+                if (negated) {
+                    str.append('-');
+                }
+                x = appendDigit(x, log10, str);
+                if (d > 0) {
+                    str.append(cdec);
+                    for (int i = 1; i <= d; i++) {
+                        x = appendDigit(x, log10 - i, str);
+                    }
+                }
+                str.append('e');
+                if (log10 < 0) {
+                    str.append('-');
+                    log10 = -log10;
+                } else {
+                    str.append('+');
+                }
+                if (shifted) {
+                    log10 += 100;
+                }
+                if (adjustedE >= 3) {
+                    str.append((char) ('0' + (log10 / 100)));
+                    log10 = log10 % 100;
+                }
+                str.append((char) ('0' + (log10 / 10)));
+                str.append((char) ('0' + (log10 % 10)));
+            } else { /* e == 0 */
+                // round towards next digit instead of truncating
+                x += DECIMAL_VALUES[-d - 1 + DECIMAL_SHIFT][5];
+
+                int log10 = x == 0 ? 0 : Math.max((int) Math.log10(x), 0);
+                int blanks = w // target width
+                                - (negated ? 1 : 0) // "-"
+                                - (log10 + 1) // digits before "."
+                                - (d > 0 ? 1 : 0) // "."
+                                - d; // digits after "."
+
+                for (int i = 0; i < blanks; i++) {
+                    str.append(' ');
+                }
+                if (negated) {
+                    str.append('-');
+                }
+                for (int i = log10; i >= 0; i--) {
+                    x = appendDigit(x, i, str);
+                }
+                if (d > 0) {
+                    str.append(cdec);
+                    for (int i = 1; i <= d; i++) {
+                        x = appendDigit(x, -i, str);
+                    }
                 }
             }
-            return prependBlanks(w, df.format(x)).replace('.', cdec);
         }
+        assert str.length() >= w;
+        return str.toString();
     }
 
-    private static String prependBlanks(int width, String id) {
-        if (id.length() >= width) {
-            return id;
-        }
-        StringBuilder str = new StringBuilder(width);
-        for (int i = 0; i < width - id.length(); i++) {
-            str.append(' ');
-        }
-        return str.append(id).toString();
+    private static double appendDigit(double x, int digit, StringBuilder str) {
+        int c = (int) (x / DECIMAL_WEIGHTS[digit + DECIMAL_SHIFT]);
+        assert c >= 0 && c <= 9;
+        str.append((char) ('0' + c));
+        return x - DECIMAL_VALUES[digit + DECIMAL_SHIFT][c];
     }
 
     public static String[] format(RAbstractDoubleVector value, boolean trim, int nsmall, int width, char decimalMark, PrintParameters pp) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/FormatMetrics.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/FormatMetrics.java
index 052d4675874c6853669d8229963763e069e200ca..c0f020d91e9eaba2f3b4519c7d60493d2ef0c40b 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/FormatMetrics.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/FormatMetrics.java
@@ -25,7 +25,7 @@ package com.oracle.truffle.r.nodes.builtin.base.printer;
 /**
  * The generic formatting metrics. N.B. This class is public since it is used in the PrettyWriter
  * public API.
- * 
+ *
  * @see PrettyWriter
  */
 public class FormatMetrics {
@@ -34,7 +34,6 @@ public class FormatMetrics {
     int maxWidth;
 
     FormatMetrics(int maxWidth) {
-        super();
         this.originalMaxWidth = maxWidth;
         this.maxWidth = maxWidth;
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/IntegerVectorPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/IntegerVectorPrinter.java
index 5453a2fa40ab27cf826ab8da4ca2a6f58cda10b8..f9d0ea7c4f89cb0cf9b1470a644d0615fee0eed6 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/IntegerVectorPrinter.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/IntegerVectorPrinter.java
@@ -46,7 +46,7 @@ public final class IntegerVectorPrinter extends VectorPrinter<RAbstractIntVector
 
         @Override
         protected FormatMetrics formatVector(int offs, int len) {
-            return formatIntVector(vector, offs, len, printCtx.parameters().getNaWidth());
+            return new FormatMetrics(formatIntVectorInternal(vector, offs, len, printCtx.parameters().getNaWidth()));
         }
 
         @Override
@@ -66,7 +66,7 @@ public final class IntegerVectorPrinter extends VectorPrinter<RAbstractIntVector
         }
     }
 
-    public static FormatMetrics formatIntVector(RAbstractIntVector x, int offs, int n, int naWidth) {
+    static int formatIntVectorInternal(RAbstractIntVector x, int offs, int n, int naWidth) {
         int xmin = RRuntime.INT_MAX_VALUE;
         int xmax = RRuntime.INT_MIN_VALUE;
         boolean naflag = false;
@@ -105,21 +105,62 @@ public final class IntegerVectorPrinter extends VectorPrinter<RAbstractIntVector
                 fieldwidth = l;
             }
         }
+        return fieldwidth;
+    }
+
+    private static final int[][] DECIMAL_VALUES = new int[10][10];
+    private static final int[] DECIMAL_WEIGHTS = new int[10];
 
-        return new FormatMetrics(fieldwidth);
+    static {
+        for (int i = 0; i < DECIMAL_WEIGHTS.length; i++) {
+            DECIMAL_WEIGHTS[i] = (int) Math.pow(10, i);
+        }
+        for (int i = 0; i < DECIMAL_VALUES.length; i++) {
+            for (int i2 = 0; i2 < 10; i2++) {
+                DECIMAL_VALUES[i][i2] = (int) (Math.pow(10, i) * i2);
+            }
+        }
     }
 
-    /*
-     * There is no documented (or enforced) limit on 'w' here, so use snprintf
-     */
-    static int NB = 1000;
+    public static String encodeInteger(int initialX, int w, PrintParameters pp) {
+        StringBuilder str = new StringBuilder(w);
 
-    public static String encodeInteger(int x, int w, PrintParameters pp) {
-        if (x == RRuntime.INT_NA) {
-            return Utils.snprintf(NB, "%" + Utils.asBlankArg(Math.min(w, (NB - 1))) + "s", pp.getNaString());
+        int x = initialX;
+        if (RRuntime.isNA(x)) {
+            String id = pp.getNaString();
+            for (int i = w - id.length(); i > 0; i--) {
+                str.append(' ');
+            }
+            str.append(id);
         } else {
-            return Utils.snprintf(NB, "%" + Utils.asBlankArg(Math.min(w, (NB - 1))) + "d", x);
+            boolean negated = false;
+            if (x < 0) {
+                negated = true;
+                x = -x;
+            }
+            int log10 = x == 0 ? 0 : (int) Math.log10(x);
+            int blanks = w // target width
+                            - (negated ? 1 : 0) // "-"
+                            - (log10 + 1); // digits
+
+            for (int i = 0; i < blanks; i++) {
+                str.append(' ');
+            }
+            if (negated) {
+                str.append('-');
+            }
+            for (int i = log10; i >= 0; i--) {
+                x = appendDigit(x, i, str);
+            }
         }
+        return str.toString();
+    }
+
+    private static int appendDigit(int x, int digit, StringBuilder str) {
+        int c = x / DECIMAL_WEIGHTS[digit];
+        assert c >= 0 && c <= 9;
+        str.append((char) ('0' + c));
+        return x - DECIMAL_VALUES[digit][c];
     }
 
     public static String[] format(RAbstractIntVector value, boolean trim, int width, PrintParameters pp) {
@@ -127,8 +168,7 @@ public final class IntegerVectorPrinter extends VectorPrinter<RAbstractIntVector
         if (trim) {
             w = 1;
         } else {
-            FormatMetrics metrics = formatIntVector(value, 0, value.getLength(), pp.getNaWidth());
-            w = metrics.maxWidth;
+            w = formatIntVectorInternal(value, 0, value.getLength(), pp.getNaWidth());
         }
         w = Math.max(w, width);
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java
index 3cde3e059f0377c95c9090efa054f8b38b05f3e0..143286861af82a99f79bd35bbf5d0f5d780dacc7 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java
@@ -78,8 +78,8 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> {
             } else if (tmp instanceof RAbstractLogicalVector) {
                 RAbstractLogicalVector lv = (RAbstractLogicalVector) tmp;
                 if (lv.getLength() == 1) {
-                    FormatMetrics fm = LogicalVectorPrinter.formatLogicalVector(lv, 0, 1, pp.getNaWidth());
-                    pbuf = LogicalVectorPrinter.encodeLogical(lv.getDataAt(0), fm.maxWidth, pp);
+                    int width = LogicalVectorPrinter.formatLogicalVectorInternal(lv, 0, 1, pp.getNaWidth());
+                    pbuf = LogicalVectorPrinter.encodeLogical(lv.getDataAt(0), width, pp);
                 } else {
                     pbuf = "Logical," + lv.getLength();
                 }
@@ -90,8 +90,8 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> {
                     pbuf = "factor," + iv.getLength();
                 } else {
                     if (iv.getLength() == 1) {
-                        FormatMetrics fm = IntegerVectorPrinter.formatIntVector(iv, 0, 1, pp.getNaWidth());
-                        pbuf = IntegerVectorPrinter.encodeInteger(iv.getDataAt(0), fm.maxWidth, pp);
+                        int width = IntegerVectorPrinter.formatIntVectorInternal(iv, 0, 1, pp.getNaWidth());
+                        pbuf = IntegerVectorPrinter.encodeInteger(iv.getDataAt(0), width, pp);
                     } else {
                         pbuf = "Integer," + iv.getLength();
                     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/LogicalVectorPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/LogicalVectorPrinter.java
index 29231624992cce41ae975e5c03bbc1b88038f6fa..3421a15d5b01f989d577a8e5b274bea67a117002 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/LogicalVectorPrinter.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/LogicalVectorPrinter.java
@@ -11,9 +11,6 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base.printer;
 
-import static com.oracle.truffle.r.nodes.builtin.base.printer.IntegerVectorPrinter.NB;
-import static com.oracle.truffle.r.nodes.builtin.base.printer.Utils.snprintf;
-
 import java.io.IOException;
 
 import com.oracle.truffle.r.runtime.RRuntime;
@@ -47,13 +44,12 @@ public final class LogicalVectorPrinter extends VectorPrinter<RAbstractLogicalVe
 
         @Override
         protected FormatMetrics formatVector(int offs, int len) {
-            return formatLogicalVector(vector, offs, len, printCtx.parameters().getNaWidth());
+            return new FormatMetrics(formatLogicalVectorInternal(vector, offs, len, printCtx.parameters().getNaWidth()));
         }
 
         @Override
         protected void printElement(int i, FormatMetrics fm) throws IOException {
-            String v = encodeLogical(vector.getDataAt(i), fm.maxWidth, printCtx.parameters());
-            out.print(v);
+            out.print(encodeLogical(vector.getDataAt(i), fm.maxWidth, printCtx.parameters()));
         }
 
         @Override
@@ -67,7 +63,7 @@ public final class LogicalVectorPrinter extends VectorPrinter<RAbstractLogicalVe
         }
     }
 
-    static FormatMetrics formatLogicalVector(RAbstractLogicalVector x, int offs, int n, int naWidth) {
+    static int formatLogicalVectorInternal(RAbstractLogicalVector x, int offs, int n, int naWidth) {
         int fieldwidth = 1;
         for (int i = 0; i < n; i++) {
             byte xi = x.getDataAt(offs + i);
@@ -83,18 +79,29 @@ public final class LogicalVectorPrinter extends VectorPrinter<RAbstractLogicalVe
                 /* this is the widest it can be, so stop */
             }
         }
-        return new FormatMetrics(fieldwidth);
+        return fieldwidth;
     }
 
     static String encodeLogical(byte x, int w, PrintParameters pp) {
-        final String fmt = "%" + Utils.asBlankArg(Math.min(w, (NB - 1))) + "s";
+        String id;
         if (x == RRuntime.LOGICAL_NA) {
-            return snprintf(NB, fmt, pp.getNaString());
-        } else if (x != 0) {
-            return snprintf(NB, fmt, "TRUE");
+            id = pp.getNaString();
+        } else if (x != RRuntime.LOGICAL_FALSE) {
+            id = "TRUE";
         } else {
-            return snprintf(NB, fmt, "FALSE");
+            id = "FALSE";
+        }
+        if (id.length() == w) {
+            return id;
+        }
+        int blanks = w // target width
+                        - id.length(); // text
+        StringBuilder str = new StringBuilder();
+        for (int i = 0; i < blanks; i++) {
+            str.append(' ');
         }
+        str.append(id);
+        return str.toString();
     }
 
     public static String[] format(RAbstractLogicalVector value, boolean trim, int width, PrintParameters pp) {
@@ -102,8 +109,7 @@ public final class LogicalVectorPrinter extends VectorPrinter<RAbstractLogicalVe
         if (trim) {
             w = 1;
         } else {
-            FormatMetrics metrics = formatLogicalVector(value, 0, value.getLength(), pp.getNaWidth());
-            w = metrics.maxWidth;
+            w = formatLogicalVectorInternal(value, 0, value.getLength(), pp.getNaWidth());
         }
         w = Math.max(w, width);