JAL-2738 copy to spikes/mungo
[jalview.git] / src / jalview / util / Format.java
index 98500da..ce7ab6d 100755 (executable)
@@ -26,6 +26,8 @@
  */
 package jalview.util;
 
+import java.util.Arrays;
+
 /**
  * DOCUMENT ME!
  * 
@@ -54,6 +56,8 @@ public class Format
 
   private char fmt; // one of cdeEfgGiosxXos
 
+  private final String formatString;
+
   /**
    * Creates a new Format object.
    * 
@@ -62,6 +66,7 @@ public class Format
    */
   public Format(String s)
   {
+    formatString = s;
     width = 0;
     precision = -1;
     pre = "";
@@ -622,7 +627,7 @@ public class Format
   /**
    * Formats a character into a string (like sprintf in C)
    * 
-   * @param x
+   * @param debounceTrap
    *          the value to format
    * @return the formatted string
    */
@@ -641,7 +646,7 @@ public class Format
   /**
    * Formats a string into a larger string (like sprintf in C)
    * 
-   * @param x
+   * @param debounceTrap
    *          the value to format
    * @return the formatted string
    */
@@ -661,30 +666,22 @@ public class Format
   }
 
   /**
-   * DOCUMENT ME!
+   * Returns a string consisting of n repeats of character c
    * 
    * @param c
-   *          DOCUMENT ME!
    * @param n
-   *          DOCUMENT ME!
    * 
-   * @return DOCUMENT ME!
+   * @return
    */
-  private static String repeat(char c, int n)
+  static String repeat(char c, int n)
   {
     if (n <= 0)
     {
       return "";
     }
-
-    StringBuffer s = new StringBuffer(n);
-
-    for (int i = 0; i < n; i++)
-    {
-      s.append(c);
-    }
-
-    return s.toString();
+    char[] chars = new char[n];
+    Arrays.fill(chars, c);
+    return new String(chars);
   }
 
   /**
@@ -793,8 +790,8 @@ public class Format
     {
       w = width;
     }
-    else if (((fmt == 'd') || (fmt == 'i') || (fmt == 'x') || (fmt == 'X') || (fmt == 'o'))
-            && (precision > 0))
+    else if (((fmt == 'd') || (fmt == 'i') || (fmt == 'x') || (fmt == 'X')
+            || (fmt == 'o')) && (precision > 0))
     {
       w = precision;
     }
@@ -836,7 +833,8 @@ public class Format
     double factor = 1;
     String leading_zeroes = "";
 
-    for (int i = 1; (i <= precision) && (factor <= 0x7FFFFFFFFFFFFFFFL); i++)
+    for (int i = 1; (i <= precision)
+            && (factor <= 0x7FFFFFFFFFFFFFFFL); i++)
     {
       factor *= 10;
       leading_zeroes = leading_zeroes + "0";
@@ -887,21 +885,18 @@ public class Format
     String f = "";
     int e = 0;
     double dd = d;
-    double factor = 1;
 
     if (d != 0)
     {
       while (dd > 10)
       {
         e++;
-        factor /= 10;
         dd = dd / 10;
       }
 
       while (dd < 1)
       {
         e--;
-        factor *= 10;
         dd = dd * 10;
       }
     }
@@ -911,8 +906,7 @@ public class Format
       return fixed_format(d);
     }
 
-    d = d * factor;
-    f = f + fixed_format(d);
+    f = f + fixed_format(dd);
 
     if ((fmt == 'e') || (fmt == 'g'))
     {
@@ -938,4 +932,55 @@ public class Format
 
     return f + p.substring(p.length() - 3, p.length());
   }
+
+  @Override
+  public String toString()
+  {
+    return formatString;
+  }
+
+  /**
+   * Bespoke method to format percentage float value to the specified number of
+   * decimal places. Avoids use of general-purpose format parsers as a
+   * processing hotspot.
+   * 
+   * @param sb
+   * @param value
+   * @param dp
+   */
+  public static void appendPercentage(StringBuilder sb, float value, int dp)
+  {
+    /*
+     * rounding first
+     */
+    double d = value;
+    long factor = 1L;
+    for (int i = 0; i < dp; i++)
+    {
+      factor *= 10;
+    }
+    d *= factor;
+    d += 0.5;
+
+    /*
+     * integer part
+     */
+    value = (float) (d / factor);
+    sb.append((long) value);
+
+    /*
+     * decimal places
+     */
+    if (dp > 0)
+    {
+      sb.append(".");
+      while (dp > 0)
+      {
+        value = value - (int) value;
+        value *= 10;
+        sb.append((int) value);
+        dp--;
+      }
+    }
+  }
 }