/* $RCSfile$ * $Author: hansonr $ * $Date: 2007-04-26 16:57:51 -0500 (Thu, 26 Apr 2007) $ * $Revision: 7502 $ * * Some portions of this file have been modified by Robert Hanson hansonr.at.stolaf.edu 2012-2017 * for use in SwingJS via transpilation into JavaScript using Java2Script. * * Copyright (C) 2005 The Jmol Development Team * * Contact: jmol-developers@lists.sf.net * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ package javajs.util; /** * created to remove ambiguities and make a simpler DecimalFormat */ public class DF { private final static String[] formattingStrings = { "0", "0.0", "0.00", "0.000", "0.0000", "0.00000", "0.000000", "0.0000000", "0.00000000", "0.000000000" }; private final static String zeros = "0000000000000000000000000000000000000000"; private final static float[] formatAdds = { 0.5f, 0.05f, 0.005f, 0.0005f, 0.00005f, 0.000005f, 0.0000005f, 0.00000005f, 0.000000005f, 0.0000000005f }; private final static Boolean[] useNumberLocalization = new Boolean[] { Boolean.TRUE }; public static void setUseNumberLocalization(boolean TF) { useNumberLocalization[0] = (TF ? Boolean.TRUE : Boolean.FALSE); } public static String formatDecimalDbl(double value, int decimalDigits) { if (decimalDigits == Integer.MAX_VALUE || value == Double.NEGATIVE_INFINITY || value == Double.POSITIVE_INFINITY || Double.isNaN(value)) return "" + value; return DF.formatDecimal((float) value, decimalDigits); } /** * a simple alternative to DecimalFormat (which Java2Script does not have * and which is quite too complex for our use here.) * * @param value * @param decimalDigits * @return formatted decimal */ public static String formatDecimal(float value, int decimalDigits) { if (decimalDigits == Integer.MAX_VALUE || value == Float.NEGATIVE_INFINITY || value == Float.POSITIVE_INFINITY || Float.isNaN(value)) return "" + value; int n; if (decimalDigits < 0) { decimalDigits = -decimalDigits; if (decimalDigits > formattingStrings.length) decimalDigits = formattingStrings.length; if (value == 0) return formattingStrings[decimalDigits - 1] + "E+0"; //scientific notation n = 0; double d; if (Math.abs(value) < 1) { n = 10; d = value * 1e-10; } else { n = -10; d = value * 1e10; } String s = ("" + d).toUpperCase(); int i = s.indexOf("E"); n = PT.parseInt(s.substring(i + 1)) + n; String sf; if (i < 0) { sf = "" + value; } else { float f = PT.parseFloat(s.substring(0, i)); if (f == 10 || f == -10) { //d = 9.99999997465; n = -6 --> 10.00000E-5 f /= 10; n += (n < 0 ? 1 : -1); } sf = formatDecimal(f, decimalDigits - 1); } return sf + "E" + (n >= 0 ? "+" : "") + n; } if (decimalDigits >= formattingStrings.length) decimalDigits = formattingStrings.length - 1; String s1 = ("" + value).toUpperCase(); int pt = s1.indexOf("."); if (pt < 0) // specifically JavaScript "-2" not "-2.0" return s1 + formattingStrings[decimalDigits].substring(1); boolean isNeg = s1.startsWith("-"); if (isNeg) { s1 = s1.substring(1); pt--; } int pt1 = s1.indexOf("E-"); if (pt1 > 0) { n = PT.parseInt(s1.substring(pt1 + 1)); // 3.567E-2 // 0.03567 s1 = "0." + zeros.substring(0, -n - 1) + s1.substring(0, 1) + s1.substring(2, pt1); pt = 1; } pt1 = s1.indexOf("E"); // 3.5678E+3 // 3567.800000000 // 1.234E10 %3.8f -> 12340000000.00000000 if (pt1 > 0) { n = PT.parseInt(s1.substring(pt1 + 1)); s1 = s1.substring(0, 1) + s1.substring(2, pt1) + zeros; s1 = s1.substring(0, n + 1) + "." + s1.substring(n + 1); pt = s1.indexOf("."); } // "234.345667 len == 10; pt = 3 // " 0.0 " decimalDigits = 1 int len = s1.length(); int pt2 = decimalDigits + pt + 1; if (pt2 < len && s1.charAt(pt2) >= '5') { return formatDecimal( value + (isNeg ? -1 : 1) * formatAdds[decimalDigits], decimalDigits); } SB sb = SB.newS(s1.substring(0, (decimalDigits == 0 ? pt : ++pt))); for (int i = 0; i < decimalDigits; i++, pt++) { if (pt < len) sb.appendC(s1.charAt(pt)); else sb.appendC('0'); } s1 = (isNeg ? "-" : "") + sb; return (Boolean.TRUE.equals(useNumberLocalization[0]) ? s1 : s1.replace(',', '.')); } /** * an alternative to DecimalFormat "0.#" * * @param x * @param precision * @return formatted number */ public static String formatDecimalTrimmed(double x, int precision) { String str = formatDecimalDbl(x, precision); int m = str.length() - 1; char zero = '0'; while (m >= 0 && str.charAt(m) == zero) m--; return str.substring(0, m + 1); // 0.##... } }