151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 2694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.misc; 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 28694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniakimport java.util.Arrays; 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class FormattedFloatingDecimal{ 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public enum Form { SCIENTIFIC, COMPATIBLE, DECIMAL_FLOAT, GENERAL }; 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak public static FormattedFloatingDecimal valueOf(double d, int precision, Form form){ 36694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak FloatingDecimal.BinaryToASCIIConverter fdConverter = 37694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak FloatingDecimal.getBinaryToASCIIConverter(d, form == Form.COMPATIBLE); 38694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak return new FormattedFloatingDecimal(precision,form, fdConverter); 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 41694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak private int decExponentRounded; 42694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak private char[] mantissa; 43694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak private char[] exponent; 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 45694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak private static final ThreadLocal<Object> threadLocalCharBuffer = 46694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak new ThreadLocal<Object>() { 47694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak @Override 48694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak protected Object initialValue() { 49694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak return new char[20]; 50694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } 51694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak }; 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 53694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak private static char[] getBuffer(){ 54694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak return (char[]) threadLocalCharBuffer.get(); 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 57694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak private FormattedFloatingDecimal(int precision, Form form, FloatingDecimal.BinaryToASCIIConverter fdConverter) { 58694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak if (fdConverter.isExceptional()) { 59694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak this.mantissa = fdConverter.toJavaFormatString().toCharArray(); 60694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak this.exponent = null; 61694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak return; 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 63694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak char[] digits = getBuffer(); 64694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak int nDigits = fdConverter.getDigits(digits); 65694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak int decExp = fdConverter.getDecimalExponent(); 66694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak int exp; 67694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak boolean isNegative = fdConverter.isNegative(); 68694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak switch (form) { 69694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak case COMPATIBLE: 70694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak exp = decExp; 71694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak this.decExponentRounded = exp; 72694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak fillCompatible(precision, digits, nDigits, exp, isNegative); 73694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak break; 74694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak case DECIMAL_FLOAT: 75694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak exp = applyPrecision(decExp, digits, nDigits, decExp + precision); 76694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak fillDecimal(precision, digits, nDigits, exp, isNegative); 77694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak this.decExponentRounded = exp; 78694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak break; 79694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak case SCIENTIFIC: 80694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak exp = applyPrecision(decExp, digits, nDigits, precision + 1); 81694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak fillScientific(precision, digits, nDigits, exp, isNegative); 82694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak this.decExponentRounded = exp; 83694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak break; 84694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak case GENERAL: 85694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak exp = applyPrecision(decExp, digits, nDigits, precision); 86694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak // adjust precision to be the number of digits to right of decimal 87694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak // the real exponent to be output is actually exp - 1, not exp 88694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak if (exp - 1 < -4 || exp - 1 >= precision) { 89694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak // form = Form.SCIENTIFIC; 90694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak precision--; 91694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak fillScientific(precision, digits, nDigits, exp, isNegative); 92694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } else { 93694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak // form = Form.DECIMAL_FLOAT; 94694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak precision = precision - exp; 95694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak fillDecimal(precision, digits, nDigits, exp, isNegative); 96694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } 97694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak this.decExponentRounded = exp; 98694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak break; 99694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak default: 100694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak assert false; 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 104694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak // returns the exponent after rounding has been done by applyPrecision 105694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak public int getExponentRounded() { 106694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak return decExponentRounded - 1; 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 109694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak public char[] getMantissa(){ 110694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak return mantissa; 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 113694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak public char[] getExponent(){ 114694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak return exponent; 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 117694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak /** 118694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak * Returns new decExp in case of overflow. 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 120694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak private static int applyPrecision(int decExp, char[] digits, int nDigits, int prec) { 121694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak if (prec >= nDigits || prec < 0) { 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // no rounding necessary 123694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak return decExp; 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 125694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak if (prec == 0) { 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // only one digit (0 or 1) is returned because the precision 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // excludes all significant digits 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (digits[0] >= '5') { 129694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak digits[0] = '1'; 130694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak Arrays.fill(digits, 1, nDigits, '0'); 131694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak return decExp + 1; 132694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } else { 133694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak Arrays.fill(digits, 0, nDigits, '0'); 134694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak return decExp; 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 137694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak int q = digits[prec]; 138694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak if (q >= '5') { 139694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak int i = prec; 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski q = digits[--i]; 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ( q == '9' ) { 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while ( q == '9' && i > 0 ){ 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski q = digits[--i]; 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ( q == '9' ){ 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // carryout! High-order 1, rest 0s, larger exp. 147694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak digits[0] = '1'; 148694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak Arrays.fill(digits, 1, nDigits, '0'); 149694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak return decExp+1; 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 152694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak digits[i] = (char)(q + 1); 153694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak Arrays.fill(digits, i+1, nDigits, '0'); 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 155694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak Arrays.fill(digits, prec, nDigits, '0'); 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 157694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak return decExp; 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 160694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak /** 161694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak * Fills mantissa and exponent char arrays for compatible format. 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 163694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak private void fillCompatible(int precision, char[] digits, int nDigits, int exp, boolean isNegative) { 164694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak int startIndex = isNegative ? 1 : 0; 165694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak if (exp > 0 && exp < 8) { 166694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak // print digits.digits. 167694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak if (nDigits < exp) { 168694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak int extraZeros = exp - nDigits; 169694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa = create(isNegative, nDigits + extraZeros + 2); 170694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak System.arraycopy(digits, 0, mantissa, startIndex, nDigits); 171694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak Arrays.fill(mantissa, startIndex + nDigits, startIndex + nDigits + extraZeros, '0'); 172694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex + nDigits + extraZeros] = '.'; 173694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex + nDigits + extraZeros+1] = '0'; 174694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } else if (exp < nDigits) { 175694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak int t = Math.min(nDigits - exp, precision); 176694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa = create(isNegative, exp + 1 + t); 177694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak System.arraycopy(digits, 0, mantissa, startIndex, exp); 178694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex + exp ] = '.'; 179694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak System.arraycopy(digits, exp, mantissa, startIndex+exp+1, t); 180694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } else { // exp == digits.length 181694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa = create(isNegative, nDigits + 2); 182694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak System.arraycopy(digits, 0, mantissa, startIndex, nDigits); 183694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex + nDigits ] = '.'; 184694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex + nDigits +1] = '0'; 185694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } 186694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } else if (exp <= 0 && exp > -3) { 187694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak int zeros = Math.max(0, Math.min(-exp, precision)); 188694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak int t = Math.max(0, Math.min(nDigits, precision + exp)); 189694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak // write '0' s before the significant digits 190694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak if (zeros > 0) { 191694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa = create(isNegative, zeros + 2 + t); 192694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex] = '0'; 193694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex+1] = '.'; 194694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak Arrays.fill(mantissa, startIndex + 2, startIndex + 2 + zeros, '0'); 195694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak if (t > 0) { 196694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak // copy only when significant digits are within the precision 197694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak System.arraycopy(digits, 0, mantissa, startIndex + 2 + zeros, t); 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 199694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } else if (t > 0) { 200694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa = create(isNegative, zeros + 2 + t); 201694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex] = '0'; 202694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex + 1] = '.'; 203694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak // copy only when significant digits are within the precision 204694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak System.arraycopy(digits, 0, mantissa, startIndex + 2, t); 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 206694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak this.mantissa = create(isNegative, 1); 207694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak this.mantissa[startIndex] = '0'; 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 210694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak if (nDigits > 1) { 211694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa = create(isNegative, nDigits + 1); 212694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex] = digits[0]; 213694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex + 1] = '.'; 214694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak System.arraycopy(digits, 1, mantissa, startIndex + 2, nDigits - 1); 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 216694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa = create(isNegative, 3); 217694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex] = digits[0]; 218694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex + 1] = '.'; 219694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex + 2] = '0'; 220694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } 221694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak int e, expStartIntex; 222694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak boolean isNegExp = (exp <= 0); 223694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak if (isNegExp) { 224694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak e = -exp + 1; 225694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak expStartIntex = 1; 226694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } else { 227694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak e = exp - 1; 228694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak expStartIntex = 0; 229694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } 230694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak // decExponent has 1, 2, or 3, digits 231694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak if (e <= 9) { 232694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak exponent = create(isNegExp,1); 233694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak exponent[expStartIntex] = (char) (e + '0'); 234694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } else if (e <= 99) { 235694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak exponent = create(isNegExp,2); 236694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak exponent[expStartIntex] = (char) (e / 10 + '0'); 237694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak exponent[expStartIntex+1] = (char) (e % 10 + '0'); 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 239694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak exponent = create(isNegExp,3); 240694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak exponent[expStartIntex] = (char) (e / 100 + '0'); 241694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak e %= 100; 242694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak exponent[expStartIntex+1] = (char) (e / 10 + '0'); 243694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak exponent[expStartIntex+2] = (char) (e % 10 + '0'); 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 248694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak private static char[] create(boolean isNegative, int size) { 249694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak if(isNegative) { 250694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak char[] r = new char[size +1]; 251694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak r[0] = '-'; 252694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak return r; 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 254694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak return new char[size]; 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 258694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak /* 259694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak * Fills mantissa char arrays for DECIMAL_FLOAT format. 260694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak * Exponent should be equal to null. 261694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak */ 262694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak private void fillDecimal(int precision, char[] digits, int nDigits, int exp, boolean isNegative) { 263694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak int startIndex = isNegative ? 1 : 0; 264694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak if (exp > 0) { 265694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak // print digits.digits. 266694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak if (nDigits < exp) { 267694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa = create(isNegative,exp); 268694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak System.arraycopy(digits, 0, mantissa, startIndex, nDigits); 269694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak Arrays.fill(mantissa, startIndex + nDigits, startIndex + exp, '0'); 270694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak // Do not append ".0" for formatted floats since the user 271694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak // may request that it be omitted. It is added as necessary 272694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak // by the Formatter. 273694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } else { 274694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak int t = Math.min(nDigits - exp, precision); 275694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa = create(isNegative, exp + (t > 0 ? (t + 1) : 0)); 276694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak System.arraycopy(digits, 0, mantissa, startIndex, exp); 277694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak // Do not append ".0" for formatted floats since the user 278694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak // may request that it be omitted. It is added as necessary 279694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak // by the Formatter. 280694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak if (t > 0) { 281694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex + exp] = '.'; 282694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak System.arraycopy(digits, exp, mantissa, startIndex + exp + 1, t); 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 285694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } else if (exp <= 0) { 286694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak int zeros = Math.max(0, Math.min(-exp, precision)); 287694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak int t = Math.max(0, Math.min(nDigits, precision + exp)); 288694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak // write '0' s before the significant digits 289694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak if (zeros > 0) { 290694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa = create(isNegative, zeros + 2 + t); 291694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex] = '0'; 292694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex+1] = '.'; 293694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak Arrays.fill(mantissa, startIndex + 2, startIndex + 2 + zeros, '0'); 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (t > 0) { 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // copy only when significant digits are within the precision 296694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak System.arraycopy(digits, 0, mantissa, startIndex + 2 + zeros, t); 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 298694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } else if (t > 0) { 299694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa = create(isNegative, zeros + 2 + t); 300694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex] = '0'; 301694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex + 1] = '.'; 302694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak // copy only when significant digits are within the precision 303694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak System.arraycopy(digits, 0, mantissa, startIndex + 2, t); 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 305694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak this.mantissa = create(isNegative, 1); 306694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak this.mantissa[startIndex] = '0'; 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 311694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak /** 312694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak * Fills mantissa and exponent char arrays for SCIENTIFIC format. 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 314694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak private void fillScientific(int precision, char[] digits, int nDigits, int exp, boolean isNegative) { 315694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak int startIndex = isNegative ? 1 : 0; 316694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak int t = Math.max(0, Math.min(nDigits - 1, precision)); 317694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak if (t > 0) { 318694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa = create(isNegative, t + 2); 319694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex] = digits[0]; 320694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex + 1] = '.'; 321694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak System.arraycopy(digits, 1, mantissa, startIndex + 2, t); 322694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } else { 323694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa = create(isNegative, 1); 324694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak mantissa[startIndex] = digits[0]; 325694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } 326694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak char expSign; 327694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak int e; 328694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak if (exp <= 0) { 329694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak expSign = '-'; 330694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak e = -exp + 1; 331694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } else { 332694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak expSign = '+' ; 333694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak e = exp - 1; 334694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } 335694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak // decExponent has 1, 2, or 3, digits 336694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak if (e <= 9) { 337694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak exponent = new char[] { expSign, 338694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak '0', (char) (e + '0') }; 339694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } else if (e <= 99) { 340694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak exponent = new char[] { expSign, 341694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak (char) (e / 10 + '0'), (char) (e % 10 + '0') }; 342694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak } else { 343694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak char hiExpChar = (char) (e / 100 + '0'); 344694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak e %= 100; 345694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak exponent = new char[] { expSign, 346694e617f54a7bfbdad24913ce96f5d56f1a1960aPrzemyslaw Szczepaniak hiExpChar, (char) (e / 10 + '0'), (char) (e % 10 + '0') }; 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 350