]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.utils/src/org/simantics/utils/format/FormattingUtil.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.utils / src / org / simantics / utils / format / FormattingUtil.java
diff --git a/bundles/org.simantics.utils/src/org/simantics/utils/format/FormattingUtil.java b/bundles/org.simantics.utils/src/org/simantics/utils/format/FormattingUtil.java
new file mode 100644 (file)
index 0000000..ae17537
--- /dev/null
@@ -0,0 +1,335 @@
+/*******************************************************************************\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 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 = floatDigits;\r
+        this.doubleDigits = doubleDigits;\r
+        this.decimalFormatSymbols = DecimalFormatSymbols.getInstance(locale);\r
+        initFormats();\r
+    }\r
+\r
+    private void initFormats() {\r
+        this.flow = createLowFormat(floatDigits);\r
+        this.fmiddles = createMiddleFormats(6, floatDigits);\r
+        this.fhigh = createHighFormat(floatDigits);\r
+        this.dlow = createLowFormat(doubleDigits);\r
+        this.dmiddles = createMiddleFormats(6, 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
+        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 static DecimalFormat[] createMiddleFormats(int formatCount, int digitCount) {\r
+        DecimalFormat[] middles = new DecimalFormat[6];\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
+            fmt.append('.');\r
+            for (; digits > 0; --digits)\r
+                fmt.append('#');\r
+            //System.out.println(fmt.toString());\r
+            middles[exp10] = new DecimalFormat(fmt.toString(), DecimalFormatSymbols.getInstance(Locale.US));\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
+    private 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 >= 0.01f) {\r
+                return flow.format(v);\r
+            } else if (abs >= 1.0f && abs < 1e6f) {\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
+    private 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 >= 0.01) {\r
+                return dlow.format(v);\r
+            } else if (abs >= 1.0 && abs < 1e6) {\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