]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.utils/src/org/simantics/utils/format/FormattingUtil.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.utils / src / org / simantics / utils / format / FormattingUtil.java
index a1a525d80f19ad735bf42c72698032a6d6159208..ab88bcaf4cd889fadf99cb14337dcc04ab2e0c70 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2014 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *     Semantum Oy - improved output precision control\r
- *******************************************************************************/\r
-package org.simantics.utils.format;\r
-\r
-import java.text.DecimalFormat;\r
-import java.text.DecimalFormatSymbols;\r
-import java.text.NumberFormat;\r
-import java.util.Locale;\r
-\r
-/**\r
- * @author Antti Villberg\r
- * @author Tuukka Lehtonen\r
- */\r
-public class FormattingUtil {\r
-\r
-    private int floatDigits;\r
-    private int doubleDigits;\r
-    private double lowLimit;\r
-    private double highLimit;\r
-    private DecimalFormatSymbols decimalFormatSymbols;\r
-\r
-    private DecimalFormat flow;\r
-    private DecimalFormat[] fmiddles;\r
-    private DecimalFormat fhigh;\r
-\r
-    private DecimalFormat dlow;\r
-    private DecimalFormat[] dmiddles;\r
-    private DecimalFormat dhigh;\r
-\r
-    public FormattingUtil(int floatDigits, int doubleDigits) {\r
-        this(floatDigits, doubleDigits, Locale.getDefault());\r
-    }\r
-    \r
-    public FormattingUtil(int floatDigits, int doubleDigits, Locale locale) {\r
-        this(floatDigits, doubleDigits, 0.01, 1e6, locale);\r
-    }\r
-\r
-    public FormattingUtil(int floatDigits, int doubleDigits, double lowLimit, double highLimit, Locale locale) {\r
-       this.floatDigits = floatDigits;\r
-        this.doubleDigits = doubleDigits;\r
-        this.lowLimit = lowLimit;\r
-        this.highLimit = highLimit;\r
-        this.decimalFormatSymbols = DecimalFormatSymbols.getInstance(locale != null ? locale : Locale.getDefault());\r
-        initFormats();\r
-    }\r
-\r
-    private void initFormats() {\r
-        this.flow = createLowFormat(floatDigits);\r
-        double exp = Math.log10(highLimit);\r
-        int formatCount = Math.max(1, (int) Math.ceil(exp));\r
-        this.fmiddles = createMiddleFormats(formatCount, floatDigits);\r
-        this.fhigh = createHighFormat(floatDigits);\r
-        this.dlow = createLowFormat(doubleDigits);\r
-        this.dmiddles = createMiddleFormats(formatCount, doubleDigits);\r
-        this.dhigh = createHighFormat(doubleDigits);\r
-    }\r
-\r
-    private DecimalFormat createLowFormat(int digitCount) {\r
-        StringBuilder fmt = new StringBuilder();\r
-        fmt.append("0.");\r
-        for (int i = 0; i < digitCount; ++i)\r
-            fmt.append('#');\r
-        //System.out.println(fmt.toString());\r
-        return new DecimalFormat(fmt.toString(), decimalFormatSymbols);\r
-    }\r
-\r
-    private DecimalFormat createHighFormat(int digitCount) {\r
-        StringBuilder fmt = new StringBuilder();\r
-        fmt.append("##0");\r
-        if (digitCount > 3) fmt.append(".");\r
-        for (int i = 3; i < digitCount; ++i)\r
-            fmt.append('#');\r
-        fmt.append("E0");\r
-        //System.out.println(fmt.toString());\r
-        return new DecimalFormat(fmt.toString(), decimalFormatSymbols);\r
-    }\r
-\r
-    private DecimalFormat[] createMiddleFormats(int formatCount, int digitCount) {\r
-        DecimalFormat[] middles = new DecimalFormat[formatCount];\r
-        for (int exp10 = 0; exp10 < formatCount; ++exp10) {\r
-            StringBuilder fmt = new StringBuilder();\r
-            int digits = digitCount;\r
-            for (int i = 0; i < exp10 && digits > 1; ++i, --digits)\r
-                fmt.append('#');\r
-            fmt.append('0');\r
-            --digits;\r
-            if (digits > 0) fmt.append('.');\r
-            for (; digits > 0; --digits)\r
-                fmt.append('#');\r
-            //System.out.println(fmt.toString());\r
-            middles[exp10] = new DecimalFormat(fmt.toString(), decimalFormatSymbols);\r
-        }\r
-        return middles;\r
-    }\r
-\r
-    public String engineeringFormat(Object value) {\r
-        if (value == null)\r
-            return "";\r
-\r
-        Class<?> clazz = value.getClass();\r
-\r
-        if (clazz == Double.class) {\r
-            return formatNumber((Double) value);\r
-        } else if (clazz == Float.class) {\r
-            return formatNumber((Float)value);\r
-        } else if (clazz == double[].class) {\r
-            double[] doubles = (double[])value;\r
-            StringBuilder b = new StringBuilder();\r
-            b.append("[");\r
-            boolean first = true;\r
-            for (double d : doubles) {\r
-                if(!first) b.append(",");\r
-                b.append(formatNumber(d));\r
-                first = false;\r
-            }\r
-            b.append("]");\r
-            return b.toString();\r
-        } else if (clazz == float[].class) {\r
-            float[] floats = (float[])value;\r
-            StringBuilder b = new StringBuilder();\r
-            b.append("[");\r
-            boolean first = true;\r
-            for (float f : floats) {\r
-                if(!first) b.append(",");\r
-                b.append(formatNumber(f));\r
-                first = false;\r
-            }\r
-            b.append("]");\r
-            return b.toString();\r
-        } else if (clazz == int[].class) {\r
-            int[] ints = (int[])value;\r
-            StringBuilder b = new StringBuilder();\r
-            b.append("[");\r
-            boolean first = true;\r
-            for (int d : ints) {\r
-                if(!first) b.append(",");\r
-                b.append(d);\r
-                first = false;\r
-            }\r
-            b.append("]");\r
-            return b.toString();\r
-        } else if (clazz == String.class) {\r
-            return (String) value;\r
-        } else {\r
-            return value.toString();\r
-        }\r
-    }\r
-\r
-    public String formatNumber(float v) {\r
-        if (Float.isInfinite(v)) {\r
-            return (v == Float.POSITIVE_INFINITY) ? "\u221E" : "-\u221E";\r
-        } else if (Float.isNaN(v)) {\r
-            return "NaN";\r
-        } else {\r
-            float abs = Math.abs(v);\r
-            if (abs < 1.0f && abs >= (float)lowLimit) {\r
-                return flow.format(v);\r
-            } else if (abs >= 1.0f && abs < (float)highLimit) {\r
-                double exp = Math.log10(abs);\r
-                int expi = (int) Math.floor(exp);\r
-//                System.out.println("format(" + v + ")");\r
-//                System.out.println("exp: " + exp);\r
-//                System.out.println("expi: " + expi);\r
-                if (expi < fmiddles.length) { \r
-                    return fmiddles[expi].format(v);\r
-                }\r
-            }\r
-            return postprocess( fhigh.format(v) );\r
-        }\r
-    }\r
-\r
-    public String formatNumber(double v) {\r
-        if (Double.isInfinite(v)) {\r
-            return (v == Double.POSITIVE_INFINITY) ? "\u221E" : "-\u221E";\r
-        } else if (Double.isNaN(v)) {\r
-            return "NaN";\r
-        } else {\r
-            double abs = Math.abs(v);\r
-            if (abs < 1.0 && abs >= lowLimit) {\r
-                return dlow.format(v);\r
-            } else if (abs >= 1.0 && abs < highLimit) {\r
-                double exp = Math.log10(abs);\r
-                int expi = (int) Math.floor(exp);\r
-//                System.out.println("format(" + v + ")");\r
-//                System.out.println("exp: " + exp);\r
-//                System.out.println("expi: " + expi);\r
-                if (expi < dmiddles.length) { \r
-                    return dmiddles[expi].format(v);\r
-                }\r
-            }\r
-            return postprocess( dhigh.format(v) );\r
-        }\r
-    }\r
-\r
-    private static String postprocess(String s) {\r
-        if (s.endsWith("E0"))\r
-            return s.substring(0, s.length() - 2);\r
-        return s.replace('E', 'e');\r
-    }\r
-\r
-    public static String formatNumberLocale(Object num, int minPrecision, int maxPrecision, String languageTag) {\r
-        NumberFormat format = NumberFormat.getNumberInstance(Locale.forLanguageTag(languageTag));\r
-        format.setMaximumFractionDigits(maxPrecision);\r
-        format.setMinimumFractionDigits(minPrecision);\r
-        if (num instanceof java.lang.Number) {\r
-               double doubleValue = ((java.lang.Number)num).doubleValue();\r
-               if(Double.isFinite(doubleValue))\r
-                       return format.format(doubleValue);\r
-               else if(Double.isNaN(doubleValue)) return "NaN";\r
-               else if(Double.isInfinite(doubleValue)) return "\u221e";\r
-        } \r
-        throw new NumberFormatException("Number " + num + ", instanceOf " + num.getClass().getName());\r
-    }    \r
-    \r
-    public static void main(String[] args) {\r
-        FormattingUtil fu = new FormattingUtil(7, 15);\r
-        System.out.println("=== DOUBLE ===");\r
-        System.out.println(fu.formatNumber(123e-3));\r
-        System.out.println(fu.formatNumber(-123e-3));\r
-        System.out.println(fu.formatNumber(Double.POSITIVE_INFINITY));\r
-        System.out.println(fu.formatNumber(Double.NEGATIVE_INFINITY));\r
-        System.out.println(fu.formatNumber(Double.NaN));\r
-        System.out.println(fu.formatNumber(0));\r
-        System.out.println(fu.formatNumber(0.25));\r
-        System.out.println(fu.formatNumber(0.1));\r
-        System.out.println(fu.formatNumber(1));\r
-        System.out.println(fu.formatNumber(-0.25));\r
-        System.out.println(fu.formatNumber(-0.1));\r
-        System.out.println(fu.formatNumber(-1));\r
-        System.out.println(fu.formatNumber(0.9999));\r
-        System.out.println(fu.formatNumber(0.0999999999999999999));\r
-        System.out.println(fu.formatNumber(0.0099999999999999999999));\r
-        System.out.println(fu.formatNumber(0.004541234));\r
-        System.out.println(fu.formatNumber(0.00099999999999999999999));\r
-        System.out.println(fu.formatNumber(0.000099999999999999999999));\r
-        System.out.println(fu.formatNumber(0.0000099999999999999999999));\r
-        System.out.println(fu.formatNumber(0.00000099999999999999999999));\r
-        System.out.println(fu.formatNumber(-0.9999));\r
-        System.out.println(fu.formatNumber(-0.0999999999999999999));\r
-        System.out.println(fu.formatNumber(-0.0099999999999999999999));\r
-        System.out.println(fu.formatNumber(-0.00099999999999999999999));\r
-        System.out.println(fu.formatNumber(-0.000099999999999999999999));\r
-        System.out.println(fu.formatNumber(1.234567891));\r
-        System.out.println(fu.formatNumber(12.34567891));\r
-        System.out.println(fu.formatNumber(123.4567891));\r
-        System.out.println(fu.formatNumber(1234.567891));\r
-        System.out.println(fu.formatNumber(12345.67891));\r
-        System.out.println(fu.formatNumber(123456.7891));\r
-        System.out.println(fu.formatNumber(1234567.891));\r
-        System.out.println(fu.formatNumber(1234567.8912345678));\r
-        System.out.println(fu.formatNumber(12345678.912345678));\r
-        System.out.println(fu.formatNumber(123456789.12345678));\r
-        System.out.println(fu.formatNumber(1234567891.2345678));\r
-        System.out.println(fu.formatNumber(12345678912.345678));\r
-        System.out.println(fu.formatNumber(100.0000000000000));\r
-        System.out.println(fu.formatNumber(100000.0000000000));\r
-        System.out.println(fu.formatNumber(1000000000.000000));\r
-        System.out.println(fu.formatNumber(100000000000.0000));\r
-        System.out.println(fu.formatNumber(10000000000000.00));\r
-        System.out.println(fu.formatNumber(999999.99999999999999));\r
-        System.out.println(fu.formatNumber(999999.9999999999999));\r
-        System.out.println(fu.formatNumber(999999.999999999999));\r
-        System.out.println(fu.formatNumber(999999.99999999999));\r
-        System.out.println(fu.formatNumber(999999.9999999999));\r
-        System.out.println(fu.formatNumber(999999.999999999));\r
-        System.out.println(fu.formatNumber(999999.99999999));\r
-        System.out.println(fu.formatNumber(999999.9999999));\r
-        System.out.println(fu.formatNumber(999999.999999));\r
-        System.out.println(fu.formatNumber(999999.99999));\r
-        System.out.println(fu.formatNumber(999999.9999));\r
-        System.out.println(fu.formatNumber(999999.999));\r
-        System.out.println(fu.formatNumber(999999.99));\r
-        System.out.println(fu.formatNumber(999999.9));\r
-        System.out.println(fu.formatNumber(999999));\r
-\r
-        System.out.println("=== FLOAT ===");\r
-        System.out.println(fu.formatNumber(123e-3f));\r
-        System.out.println(fu.formatNumber(-123e-3f));\r
-        System.out.println(fu.formatNumber(Float.POSITIVE_INFINITY));\r
-        System.out.println(fu.formatNumber(Float.NEGATIVE_INFINITY));\r
-        System.out.println(fu.formatNumber(Float.NaN));\r
-        System.out.println(fu.formatNumber(0f));\r
-        System.out.println(fu.formatNumber(0.25f));\r
-        System.out.println(fu.formatNumber(0.1f));\r
-        System.out.println(fu.formatNumber(1f));\r
-        System.out.println(fu.formatNumber(-0.25f));\r
-        System.out.println(fu.formatNumber(-0.1f));\r
-        System.out.println(fu.formatNumber(-1f));\r
-        System.out.println(fu.formatNumber(0.9999f));\r
-        System.out.println(fu.formatNumber(0.0999999999999999999f));\r
-        System.out.println(fu.formatNumber(0.0099999999999999999999f));\r
-        System.out.println(fu.formatNumber(0.004541234f));\r
-        System.out.println(fu.formatNumber(0.00099999999999999999999f));\r
-        System.out.println(fu.formatNumber(0.000099999999999999999999f));\r
-        System.out.println(fu.formatNumber(0.0000099999999999999999999f));\r
-        System.out.println(fu.formatNumber(0.00000099999999999999999999f));\r
-        System.out.println(fu.formatNumber(-0.9999f));\r
-        System.out.println(fu.formatNumber(-0.0999999999999999999f));\r
-        System.out.println(fu.formatNumber(-0.0099999999999999999999f));\r
-        System.out.println(fu.formatNumber(-0.00099999999999999999999f));\r
-        System.out.println(fu.formatNumber(-0.000099999999999999999999f));\r
-        System.out.println(fu.formatNumber(1.234567891f));\r
-        System.out.println(fu.formatNumber(12.34567891f));\r
-        System.out.println(fu.formatNumber(123.4567891f));\r
-        System.out.println(fu.formatNumber(1234.567891f));\r
-        System.out.println(fu.formatNumber(12345.67891f));\r
-        System.out.println(fu.formatNumber(123456.7891f));\r
-        System.out.println(fu.formatNumber(1234567.891f));\r
-        System.out.println(fu.formatNumber(1234567.8912345678f));\r
-        System.out.println(fu.formatNumber(12345678.912345678f));\r
-        System.out.println(fu.formatNumber(123456789.12345678f));\r
-        System.out.println(fu.formatNumber(1234567891.2345678f));\r
-        System.out.println(fu.formatNumber(12345678912.345678f));\r
-        System.out.println(fu.formatNumber(100.0000000000000f));\r
-        System.out.println(fu.formatNumber(100000.0000000000f));\r
-        System.out.println(fu.formatNumber(1000000000.000000f));\r
-        System.out.println(fu.formatNumber(100000000000.0000f));\r
-        System.out.println(fu.formatNumber(10000000000000.00f));\r
-        System.out.println(fu.formatNumber(999999.99999999999999f));\r
-        System.out.println(fu.formatNumber(999999.9999999999999f));\r
-        System.out.println(fu.formatNumber(999999.999999999999f));\r
-        System.out.println(fu.formatNumber(999999.99999999999f));\r
-        System.out.println(fu.formatNumber(999999.9999999999f));\r
-        System.out.println(fu.formatNumber(999999.999999999f));\r
-        System.out.println(fu.formatNumber(999999.99999999f));\r
-        System.out.println(fu.formatNumber(999999.9999999f));\r
-        System.out.println(fu.formatNumber(999999.999999f));\r
-        System.out.println(fu.formatNumber(999999.99999f));\r
-        System.out.println(fu.formatNumber(999999.9999f));\r
-        System.out.println(fu.formatNumber(999999.999f));\r
-        System.out.println(fu.formatNumber(999999.99f));\r
-        System.out.println(fu.formatNumber(999999.9f));\r
-        System.out.println(fu.formatNumber(999999f));\r
-    }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2014 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *     Semantum Oy - improved output precision control
+ *******************************************************************************/
+package org.simantics.utils.format;
+
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.util.Locale;
+
+/**
+ * @author Antti Villberg
+ * @author Tuukka Lehtonen
+ */
+public class FormattingUtil {
+
+    private int floatDigits;
+    private int doubleDigits;
+    private double lowLimit;
+    private double highLimit;
+    private DecimalFormatSymbols decimalFormatSymbols;
+
+    private DecimalFormat flow;
+    private DecimalFormat[] fmiddles;
+    private DecimalFormat fhigh;
+
+    private DecimalFormat dlow;
+    private DecimalFormat[] dmiddles;
+    private DecimalFormat dhigh;
+
+    public FormattingUtil(int floatDigits, int doubleDigits) {
+        this(floatDigits, doubleDigits, Locale.getDefault());
+    }
+    
+    public FormattingUtil(int floatDigits, int doubleDigits, Locale locale) {
+        this(floatDigits, doubleDigits, 0.01, 1e6, locale);
+    }
+
+    public FormattingUtil(int floatDigits, int doubleDigits, double lowLimit, double highLimit, Locale locale) {
+       this.floatDigits = floatDigits;
+        this.doubleDigits = doubleDigits;
+        this.lowLimit = lowLimit;
+        this.highLimit = highLimit;
+        this.decimalFormatSymbols = DecimalFormatSymbols.getInstance(locale != null ? locale : Locale.getDefault());
+        initFormats();
+    }
+
+    private void initFormats() {
+        this.flow = createLowFormat(floatDigits);
+        double exp = Math.log10(highLimit);
+        int formatCount = Math.max(1, (int) Math.ceil(exp));
+        this.fmiddles = createMiddleFormats(formatCount, floatDigits);
+        this.fhigh = createHighFormat(floatDigits);
+        this.dlow = createLowFormat(doubleDigits);
+        this.dmiddles = createMiddleFormats(formatCount, doubleDigits);
+        this.dhigh = createHighFormat(doubleDigits);
+    }
+
+    private DecimalFormat createLowFormat(int digitCount) {
+        StringBuilder fmt = new StringBuilder();
+        fmt.append("0.");
+        for (int i = 0; i < digitCount; ++i)
+            fmt.append('#');
+        //System.out.println(fmt.toString());
+        return new DecimalFormat(fmt.toString(), decimalFormatSymbols);
+    }
+
+    private DecimalFormat createHighFormat(int digitCount) {
+        StringBuilder fmt = new StringBuilder();
+        fmt.append("##0");
+        if (digitCount > 3) fmt.append(".");
+        for (int i = 3; i < digitCount; ++i)
+            fmt.append('#');
+        fmt.append("E0");
+        //System.out.println(fmt.toString());
+        return new DecimalFormat(fmt.toString(), decimalFormatSymbols);
+    }
+
+    private DecimalFormat[] createMiddleFormats(int formatCount, int digitCount) {
+        DecimalFormat[] middles = new DecimalFormat[formatCount];
+        for (int exp10 = 0; exp10 < formatCount; ++exp10) {
+            StringBuilder fmt = new StringBuilder();
+            int digits = digitCount;
+            for (int i = 0; i < exp10 && digits > 1; ++i, --digits)
+                fmt.append('#');
+            fmt.append('0');
+            --digits;
+            if (digits > 0) fmt.append('.');
+            for (; digits > 0; --digits)
+                fmt.append('#');
+            //System.out.println(fmt.toString());
+            middles[exp10] = new DecimalFormat(fmt.toString(), decimalFormatSymbols);
+        }
+        return middles;
+    }
+
+    public String engineeringFormat(Object value) {
+        if (value == null)
+            return "";
+
+        Class<?> clazz = value.getClass();
+
+        if (clazz == Double.class) {
+            return formatNumber((Double) value);
+        } else if (clazz == Float.class) {
+            return formatNumber((Float)value);
+        } else if (clazz == double[].class) {
+            double[] doubles = (double[])value;
+            StringBuilder b = new StringBuilder();
+            b.append("[");
+            boolean first = true;
+            for (double d : doubles) {
+                if(!first) b.append(",");
+                b.append(formatNumber(d));
+                first = false;
+            }
+            b.append("]");
+            return b.toString();
+        } else if (clazz == float[].class) {
+            float[] floats = (float[])value;
+            StringBuilder b = new StringBuilder();
+            b.append("[");
+            boolean first = true;
+            for (float f : floats) {
+                if(!first) b.append(",");
+                b.append(formatNumber(f));
+                first = false;
+            }
+            b.append("]");
+            return b.toString();
+        } else if (clazz == int[].class) {
+            int[] ints = (int[])value;
+            StringBuilder b = new StringBuilder();
+            b.append("[");
+            boolean first = true;
+            for (int d : ints) {
+                if(!first) b.append(",");
+                b.append(d);
+                first = false;
+            }
+            b.append("]");
+            return b.toString();
+        } else if (clazz == String.class) {
+            return (String) value;
+        } else {
+            return value.toString();
+        }
+    }
+
+    public String formatNumber(float v) {
+        if (Float.isInfinite(v)) {
+            return (v == Float.POSITIVE_INFINITY) ? "\u221E" : "-\u221E";
+        } else if (Float.isNaN(v)) {
+            return "NaN";
+        } else {
+            float abs = Math.abs(v);
+            if (abs < 1.0f && abs >= (float)lowLimit) {
+                return flow.format(v);
+            } else if (abs >= 1.0f && abs < (float)highLimit) {
+                double exp = Math.log10(abs);
+                int expi = (int) Math.floor(exp);
+//                System.out.println("format(" + v + ")");
+//                System.out.println("exp: " + exp);
+//                System.out.println("expi: " + expi);
+                if (expi < fmiddles.length) { 
+                    return fmiddles[expi].format(v);
+                }
+            }
+            return postprocess( fhigh.format(v) );
+        }
+    }
+
+    public String formatNumber(double v) {
+        if (Double.isInfinite(v)) {
+            return (v == Double.POSITIVE_INFINITY) ? "\u221E" : "-\u221E";
+        } else if (Double.isNaN(v)) {
+            return "NaN";
+        } else {
+            double abs = Math.abs(v);
+            if (abs < 1.0 && abs >= lowLimit) {
+                return dlow.format(v);
+            } else if (abs >= 1.0 && abs < highLimit) {
+                double exp = Math.log10(abs);
+                int expi = (int) Math.floor(exp);
+//                System.out.println("format(" + v + ")");
+//                System.out.println("exp: " + exp);
+//                System.out.println("expi: " + expi);
+                if (expi < dmiddles.length) { 
+                    return dmiddles[expi].format(v);
+                }
+            }
+            return postprocess( dhigh.format(v) );
+        }
+    }
+
+    private static String postprocess(String s) {
+        if (s.endsWith("E0"))
+            return s.substring(0, s.length() - 2);
+        return s.replace('E', 'e');
+    }
+
+    public static String formatNumberLocale(Object num, int minPrecision, int maxPrecision, String languageTag) {
+        NumberFormat format = NumberFormat.getNumberInstance(Locale.forLanguageTag(languageTag));
+        format.setMaximumFractionDigits(maxPrecision);
+        format.setMinimumFractionDigits(minPrecision);
+        if (num instanceof java.lang.Number) {
+               double doubleValue = ((java.lang.Number)num).doubleValue();
+               if(Double.isFinite(doubleValue))
+                       return format.format(doubleValue);
+               else if(Double.isNaN(doubleValue)) return "NaN";
+               else if(Double.isInfinite(doubleValue)) return "\u221e";
+        } 
+        throw new NumberFormatException("Number " + num + ", instanceOf " + num.getClass().getName());
+    }    
+    
+    public static void main(String[] args) {
+        FormattingUtil fu = new FormattingUtil(7, 15);
+        System.out.println("=== DOUBLE ===");
+        System.out.println(fu.formatNumber(123e-3));
+        System.out.println(fu.formatNumber(-123e-3));
+        System.out.println(fu.formatNumber(Double.POSITIVE_INFINITY));
+        System.out.println(fu.formatNumber(Double.NEGATIVE_INFINITY));
+        System.out.println(fu.formatNumber(Double.NaN));
+        System.out.println(fu.formatNumber(0));
+        System.out.println(fu.formatNumber(0.25));
+        System.out.println(fu.formatNumber(0.1));
+        System.out.println(fu.formatNumber(1));
+        System.out.println(fu.formatNumber(-0.25));
+        System.out.println(fu.formatNumber(-0.1));
+        System.out.println(fu.formatNumber(-1));
+        System.out.println(fu.formatNumber(0.9999));
+        System.out.println(fu.formatNumber(0.0999999999999999999));
+        System.out.println(fu.formatNumber(0.0099999999999999999999));
+        System.out.println(fu.formatNumber(0.004541234));
+        System.out.println(fu.formatNumber(0.00099999999999999999999));
+        System.out.println(fu.formatNumber(0.000099999999999999999999));
+        System.out.println(fu.formatNumber(0.0000099999999999999999999));
+        System.out.println(fu.formatNumber(0.00000099999999999999999999));
+        System.out.println(fu.formatNumber(-0.9999));
+        System.out.println(fu.formatNumber(-0.0999999999999999999));
+        System.out.println(fu.formatNumber(-0.0099999999999999999999));
+        System.out.println(fu.formatNumber(-0.00099999999999999999999));
+        System.out.println(fu.formatNumber(-0.000099999999999999999999));
+        System.out.println(fu.formatNumber(1.234567891));
+        System.out.println(fu.formatNumber(12.34567891));
+        System.out.println(fu.formatNumber(123.4567891));
+        System.out.println(fu.formatNumber(1234.567891));
+        System.out.println(fu.formatNumber(12345.67891));
+        System.out.println(fu.formatNumber(123456.7891));
+        System.out.println(fu.formatNumber(1234567.891));
+        System.out.println(fu.formatNumber(1234567.8912345678));
+        System.out.println(fu.formatNumber(12345678.912345678));
+        System.out.println(fu.formatNumber(123456789.12345678));
+        System.out.println(fu.formatNumber(1234567891.2345678));
+        System.out.println(fu.formatNumber(12345678912.345678));
+        System.out.println(fu.formatNumber(100.0000000000000));
+        System.out.println(fu.formatNumber(100000.0000000000));
+        System.out.println(fu.formatNumber(1000000000.000000));
+        System.out.println(fu.formatNumber(100000000000.0000));
+        System.out.println(fu.formatNumber(10000000000000.00));
+        System.out.println(fu.formatNumber(999999.99999999999999));
+        System.out.println(fu.formatNumber(999999.9999999999999));
+        System.out.println(fu.formatNumber(999999.999999999999));
+        System.out.println(fu.formatNumber(999999.99999999999));
+        System.out.println(fu.formatNumber(999999.9999999999));
+        System.out.println(fu.formatNumber(999999.999999999));
+        System.out.println(fu.formatNumber(999999.99999999));
+        System.out.println(fu.formatNumber(999999.9999999));
+        System.out.println(fu.formatNumber(999999.999999));
+        System.out.println(fu.formatNumber(999999.99999));
+        System.out.println(fu.formatNumber(999999.9999));
+        System.out.println(fu.formatNumber(999999.999));
+        System.out.println(fu.formatNumber(999999.99));
+        System.out.println(fu.formatNumber(999999.9));
+        System.out.println(fu.formatNumber(999999));
+
+        System.out.println("=== FLOAT ===");
+        System.out.println(fu.formatNumber(123e-3f));
+        System.out.println(fu.formatNumber(-123e-3f));
+        System.out.println(fu.formatNumber(Float.POSITIVE_INFINITY));
+        System.out.println(fu.formatNumber(Float.NEGATIVE_INFINITY));
+        System.out.println(fu.formatNumber(Float.NaN));
+        System.out.println(fu.formatNumber(0f));
+        System.out.println(fu.formatNumber(0.25f));
+        System.out.println(fu.formatNumber(0.1f));
+        System.out.println(fu.formatNumber(1f));
+        System.out.println(fu.formatNumber(-0.25f));
+        System.out.println(fu.formatNumber(-0.1f));
+        System.out.println(fu.formatNumber(-1f));
+        System.out.println(fu.formatNumber(0.9999f));
+        System.out.println(fu.formatNumber(0.0999999999999999999f));
+        System.out.println(fu.formatNumber(0.0099999999999999999999f));
+        System.out.println(fu.formatNumber(0.004541234f));
+        System.out.println(fu.formatNumber(0.00099999999999999999999f));
+        System.out.println(fu.formatNumber(0.000099999999999999999999f));
+        System.out.println(fu.formatNumber(0.0000099999999999999999999f));
+        System.out.println(fu.formatNumber(0.00000099999999999999999999f));
+        System.out.println(fu.formatNumber(-0.9999f));
+        System.out.println(fu.formatNumber(-0.0999999999999999999f));
+        System.out.println(fu.formatNumber(-0.0099999999999999999999f));
+        System.out.println(fu.formatNumber(-0.00099999999999999999999f));
+        System.out.println(fu.formatNumber(-0.000099999999999999999999f));
+        System.out.println(fu.formatNumber(1.234567891f));
+        System.out.println(fu.formatNumber(12.34567891f));
+        System.out.println(fu.formatNumber(123.4567891f));
+        System.out.println(fu.formatNumber(1234.567891f));
+        System.out.println(fu.formatNumber(12345.67891f));
+        System.out.println(fu.formatNumber(123456.7891f));
+        System.out.println(fu.formatNumber(1234567.891f));
+        System.out.println(fu.formatNumber(1234567.8912345678f));
+        System.out.println(fu.formatNumber(12345678.912345678f));
+        System.out.println(fu.formatNumber(123456789.12345678f));
+        System.out.println(fu.formatNumber(1234567891.2345678f));
+        System.out.println(fu.formatNumber(12345678912.345678f));
+        System.out.println(fu.formatNumber(100.0000000000000f));
+        System.out.println(fu.formatNumber(100000.0000000000f));
+        System.out.println(fu.formatNumber(1000000000.000000f));
+        System.out.println(fu.formatNumber(100000000000.0000f));
+        System.out.println(fu.formatNumber(10000000000000.00f));
+        System.out.println(fu.formatNumber(999999.99999999999999f));
+        System.out.println(fu.formatNumber(999999.9999999999999f));
+        System.out.println(fu.formatNumber(999999.999999999999f));
+        System.out.println(fu.formatNumber(999999.99999999999f));
+        System.out.println(fu.formatNumber(999999.9999999999f));
+        System.out.println(fu.formatNumber(999999.999999999f));
+        System.out.println(fu.formatNumber(999999.99999999f));
+        System.out.println(fu.formatNumber(999999.9999999f));
+        System.out.println(fu.formatNumber(999999.999999f));
+        System.out.println(fu.formatNumber(999999.99999f));
+        System.out.println(fu.formatNumber(999999.9999f));
+        System.out.println(fu.formatNumber(999999.999f));
+        System.out.println(fu.formatNumber(999999.99f));
+        System.out.println(fu.formatNumber(999999.9f));
+        System.out.println(fu.formatNumber(999999f));
+    }
+
+}