JAL-1807 Bob's JalviewJS prototype first commit
[jalviewjs.git] / src / javajs / util / DF.java
1 /* $RCSfile$\r
2  * $Author: hansonr $\r
3  * $Date: 2007-04-26 16:57:51 -0500 (Thu, 26 Apr 2007) $\r
4  * $Revision: 7502 $\r
5  *\r
6  * Copyright (C) 2005  The Jmol Development Team\r
7  *\r
8  * Contact: jmol-developers@lists.sf.net\r
9  *\r
10  *  This library is free software; you can redistribute it and/or\r
11  *  modify it under the terms of the GNU Lesser General Public\r
12  *  License as published by the Free Software Foundation; either\r
13  *  version 2.1 of the License, or (at your option) any later version.\r
14  *\r
15  *  This library is distributed in the hope that it will be useful,\r
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
18  *  Lesser General Public License for more details.\r
19  *\r
20  *  You should have received a copy of the GNU Lesser General Public\r
21  *  License along with this library; if not, write to the Free Software\r
22  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\r
23  */\r
24 \r
25 package javajs.util;\r
26 \r
27 /**\r
28  * created to remove ambiguities and make a simpler DecimalFormat\r
29  */\r
30 public class DF {\r
31 \r
32   private final static String[] formattingStrings = { "0", "0.0", "0.00",\r
33       "0.000", "0.0000", "0.00000", "0.000000", "0.0000000", "0.00000000",\r
34       "0.000000000" };\r
35   private final static String zeros = "0000000000000000000000000000000000000000";\r
36 \r
37   private final static float[] formatAdds = { 0.5f, 0.05f, 0.005f, 0.0005f,\r
38       0.00005f, 0.000005f, 0.0000005f, 0.00000005f, 0.000000005f, 0.0000000005f };\r
39 \r
40   private final static Boolean[] useNumberLocalization = new Boolean[] { Boolean.TRUE };\r
41 \r
42   public static void setUseNumberLocalization(boolean TF) {\r
43     useNumberLocalization[0] = (TF ? Boolean.TRUE : Boolean.FALSE);\r
44   }\r
45 \r
46   public static String formatDecimalDbl(double value, int decimalDigits) {\r
47     if (decimalDigits == Integer.MAX_VALUE \r
48         || value == Double.NEGATIVE_INFINITY\r
49         || value == Double.POSITIVE_INFINITY \r
50         || Double.isNaN(value))\r
51       return "" + value;\r
52     return DF.formatDecimal((float) value, decimalDigits);\r
53   }\r
54 \r
55   /**\r
56    * a simple alternative to DecimalFormat (which Java2Script does not have\r
57    * and which is quite too complex for our use here.)\r
58    * \r
59    * @param value\r
60    * @param decimalDigits\r
61    * @return  formatted decimal\r
62    */\r
63   public static String formatDecimal(float value, int decimalDigits) {\r
64     if (decimalDigits == Integer.MAX_VALUE \r
65         || value == Float.NEGATIVE_INFINITY || value == Float.POSITIVE_INFINITY || Float.isNaN(value))\r
66       return "" + value;\r
67     int n;\r
68     if (decimalDigits < 0) {\r
69       decimalDigits = -decimalDigits;\r
70       if (decimalDigits > formattingStrings.length)\r
71         decimalDigits = formattingStrings.length;\r
72       if (value == 0)\r
73         return formattingStrings[decimalDigits] + "E+0";\r
74       //scientific notation\r
75       n = 0;\r
76       double d;\r
77       if (Math.abs(value) < 1) {\r
78         n = 10;\r
79         d = value * 1e-10;\r
80       } else {\r
81         n = -10;\r
82         d = value * 1e10;\r
83       }\r
84       String s = ("" + d).toUpperCase();\r
85       int i = s.indexOf("E");\r
86       n = PT.parseInt(s.substring(i + 1)) + n;\r
87       return (i < 0 ? "" + value : formatDecimal(PT.parseFloat(s.substring(\r
88           0, i)), decimalDigits - 1)\r
89           + "E" + (n >= 0 ? "+" : "") + n);\r
90     }\r
91   \r
92     if (decimalDigits >= formattingStrings.length)\r
93       decimalDigits = formattingStrings.length - 1;\r
94     String s1 = ("" + value).toUpperCase();\r
95     int pt = s1.indexOf(".");\r
96     if (pt < 0) // specifically JavaScript "-2" not "-2.0"\r
97       return s1 + formattingStrings[decimalDigits].substring(1);\r
98     boolean isNeg = s1.startsWith("-");\r
99     if (isNeg) {\r
100       s1 = s1.substring(1);\r
101       pt--;\r
102     }\r
103     int pt1 = s1.indexOf("E-");\r
104     if (pt1 > 0) {\r
105       n = PT.parseInt(s1.substring(pt1 + 1));\r
106       // 3.567E-2\r
107       // 0.03567\r
108       s1 = "0." + zeros.substring(0, -n - 1) + s1.substring(0, 1) + s1.substring(2, pt1);\r
109       pt = 1; \r
110     }\r
111   \r
112     pt1 = s1.indexOf("E");\r
113     // 3.5678E+3\r
114     // 3567.800000000\r
115     // 1.234E10 %3.8f -> 12340000000.00000000\r
116     if (pt1 > 0) {\r
117       n = PT.parseInt(s1.substring(pt1 + 1));\r
118       s1 = s1.substring(0, 1) + s1.substring(2, pt1) + zeros;\r
119       s1 = s1.substring(0, n + 1) + "." + s1.substring(n + 1);\r
120       pt = s1.indexOf(".");\r
121     } \r
122     // "234.345667  len == 10; pt = 3\r
123     // "  0.0 "  decimalDigits = 1\r
124     \r
125     int len = s1.length();\r
126     int pt2 = decimalDigits + pt + 1;\r
127     if (pt2 < len && s1.charAt(pt2) >= '5') {\r
128       return formatDecimal(\r
129           value + (isNeg ? -1 : 1) * formatAdds[decimalDigits], decimalDigits);\r
130     }\r
131   \r
132     SB sb = SB.newS(s1.substring(0, (decimalDigits == 0 ? pt\r
133         : ++pt)));\r
134     for (int i = 0; i < decimalDigits; i++, pt++) {\r
135       if (pt < len)\r
136         sb.appendC(s1.charAt(pt));\r
137       else\r
138         sb.appendC('0');\r
139     }\r
140     s1 = (isNeg ? "-" : "") + sb;\r
141     return (Boolean.TRUE.equals(useNumberLocalization[0]) ? s1 : s1.replace(',',\r
142         '.'));\r
143   }\r
144 \r
145   /**\r
146    * an alternative to DecimalFormat "0.#"\r
147    * \r
148    * @param x\r
149    * @param precision\r
150    * @return  formatted number \r
151    */\r
152   public static String formatDecimalTrimmed(double x, int precision) {\r
153     String str = formatDecimalDbl(x, precision);\r
154     int m = str.length() - 1;\r
155     char zero = '0';\r
156     while (m >= 0 && str.charAt(m) == zero)\r
157       m--;\r
158     return str.substring(0, m + 1); // 0.##...\r
159   }\r
160 \r
161 }\r