1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this work for additional information regarding copyright ownership. 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (the "License"); you may not use this file except in compliance with 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the License. You may obtain a copy of the License at 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage org.apache.harmony.luni.util; 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class NumberConverter { 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int setCount; // number of times u and k have been gotten 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int getCount; // number of times u and k have been set 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int[] uArray = new int[64]; 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int firstK; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final static double invLogOfTenBaseTwo = Math.log(2.0) 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project / Math.log(10.0); 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final static long[] TEN_TO_THE = new long[20]; 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static { 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TEN_TO_THE[0] = 1L; 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 1; i < TEN_TO_THE.length; ++i) { 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long previous = TEN_TO_THE[i - 1]; 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TEN_TO_THE[i] = (previous << 1) + (previous << 3); 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static NumberConverter getConverter() { 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new NumberConverter(); 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static String convert(double input) { 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return getConverter().convertD(input); 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static String convert(float input) { 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return getConverter().convertF(input); 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String convertD(double inputNumber) { 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int p = 1023 + 52; // the power offset (precision) 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long signMask = 0x8000000000000000L; // the mask to get the sign of 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // the number 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long eMask = 0x7FF0000000000000L; // the mask to get the power bits 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long fMask = 0x000FFFFFFFFFFFFFL; // the mask to get the significand 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // bits 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long inputNumberBits = Double.doubleToLongBits(inputNumber); 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // the value of the sign... 0 is positive, ~0 is negative 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String signString = (inputNumberBits & signMask) == 0 ? "" : "-"; 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // the value of the 'power bits' of the inputNumber 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int e = (int) ((inputNumberBits & eMask) >> 52); 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // the value of the 'significand bits' of the inputNumber 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long f = inputNumberBits & fMask; 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean mantissaIsZero = f == 0; 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int pow = 0, numBits = 52; 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (e == 2047) 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return mantissaIsZero ? signString + "Infinity" : "NaN"; 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (e == 0) { 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mantissaIsZero) 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return signString + "0.0"; 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (f == 1) 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // special case to increase precision even though 2 * 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Double.MIN_VALUE is 1.0e-323 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return signString + "4.9E-324"; 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pow = 1 - p; // a denormalized number 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long ff = f; 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while ((ff & 0x0010000000000000L) == 0) { 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ff = ff << 1; 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project numBits--; 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 0 < e < 2047 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // a "normalized" number 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project f = f | 0x0010000000000000L; 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pow = e - p; 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (-59 < pow && pow < 6 || (pow == -59 && !mantissaIsZero)) 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project longDigitGenerator(f, pow, e == 0, mantissaIsZero, numBits); 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bigIntDigitGeneratorInstImpl(f, pow, e == 0, mantissaIsZero, 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project numBits); 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (inputNumber >= 1e7D || inputNumber <= -1e7D 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project || (inputNumber > -1e-3D && inputNumber < 1e-3D)) 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return signString + freeFormatExponential(); 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return signString + freeFormat(); 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String convertF(float inputNumber) { 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int p = 127 + 23; // the power offset (precision) 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int signMask = 0x80000000; // the mask to get the sign of the number 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int eMask = 0x7F800000; // the mask to get the power bits 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int fMask = 0x007FFFFF; // the mask to get the significand bits 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int inputNumberBits = Float.floatToIntBits(inputNumber); 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // the value of the sign... 0 is positive, ~0 is negative 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String signString = (inputNumberBits & signMask) == 0 ? "" : "-"; 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // the value of the 'power bits' of the inputNumber 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int e = (inputNumberBits & eMask) >> 23; 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // the value of the 'significand bits' of the inputNumber 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int f = inputNumberBits & fMask; 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean mantissaIsZero = f == 0; 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int pow = 0, numBits = 23; 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (e == 255) 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return mantissaIsZero ? signString + "Infinity" : "NaN"; 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (e == 0) { 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mantissaIsZero) 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return signString + "0.0"; 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pow = 1 - p; // a denormalized number 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (f < 8) { // want more precision with smallest values 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project f = f << 2; 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pow -= 2; 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ff = f; 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while ((ff & 0x00800000) == 0) { 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ff = ff << 1; 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project numBits--; 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 0 < e < 255 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // a "normalized" number 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project f = f | 0x00800000; 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pow = e - p; 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (-59 < pow && pow < 35 || (pow == -59 && !mantissaIsZero)) 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project longDigitGenerator(f, pow, e == 0, mantissaIsZero, numBits); 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bigIntDigitGeneratorInstImpl(f, pow, e == 0, mantissaIsZero, 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project numBits); 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (inputNumber >= 1e7f || inputNumber <= -1e7f 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project || (inputNumber > -1e-3f && inputNumber < 1e-3f)) 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return signString + freeFormatExponential(); 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return signString + freeFormat(); 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private String freeFormatExponential() { 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // corresponds to process "Free-Format Exponential" 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char[] formattedDecimal = new char[25]; 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project formattedDecimal[0] = (char) ('0' + uArray[getCount++]); 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project formattedDecimal[1] = '.'; 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // the position the next character is to be inserted into 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // formattedDecimal 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int charPos = 2; 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int k = firstK; 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int expt = k; 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (true) { 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project k--; 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (getCount >= setCount) 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project formattedDecimal[charPos++] = (char) ('0' + uArray[getCount++]); 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (k == expt - 1) 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project formattedDecimal[charPos++] = '0'; 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project formattedDecimal[charPos++] = 'E'; 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new String(formattedDecimal, 0, charPos) 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + Integer.toString(expt); 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private String freeFormat() { 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // corresponds to process "Free-Format" 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char[] formattedDecimal = new char[25]; 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // the position the next character is to be inserted into 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // formattedDecimal 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int charPos = 0; 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int k = firstK; 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (k < 0) { 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project formattedDecimal[0] = '0'; 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project formattedDecimal[1] = '.'; 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project charPos += 2; 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = k + 1; i < 0; i++) 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project formattedDecimal[charPos++] = '0'; 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int U = uArray[getCount++]; 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project do { 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (U != -1) 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project formattedDecimal[charPos++] = (char) ('0' + U); 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else if (k >= -1) 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project formattedDecimal[charPos++] = '0'; 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (k == 0) 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project formattedDecimal[charPos++] = '.'; 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project k--; 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project U = getCount < setCount ? uArray[getCount++] : -1; 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } while (U != -1 || k >= -1); 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new String(formattedDecimal, 0, charPos); 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private native void bigIntDigitGeneratorInstImpl(long f, int e, 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean isDenormalized, boolean mantissaIsZero, int p); 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void longDigitGenerator(long f, int e, boolean isDenormalized, 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean mantissaIsZero, int p) { 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long R, S, M; 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (e >= 0) { 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project M = 1l << e; 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!mantissaIsZero) { 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project R = f << (e + 1); 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project S = 2; 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project R = f << (e + 2); 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project S = 4; 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project M = 1; 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isDenormalized || !mantissaIsZero) { 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project R = f << 1; 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project S = 1l << (1 - e); 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project R = f << 2; 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project S = 1l << (2 - e); 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int k = (int) Math.ceil((e + p - 1) * invLogOfTenBaseTwo - 1e-10); 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (k > 0) { 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project S = S * TEN_TO_THE[k]; 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (k < 0) { 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long scale = TEN_TO_THE[-k]; 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project R = R * scale; 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project M = M == 1 ? scale : M * scale; 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (R + M > S) { // was M_plus 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project firstK = k; 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project firstK = k - 1; 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project R = R * 10; 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project M = M * 10; 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project getCount = setCount = 0; // reset indices 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean low, high; 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int U; 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long[] Si = new long[] { S, S << 1, S << 2, S << 3 }; 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (true) { 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // set U to be floor (R / S) and R to be the remainder 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // using a kind of "binary search" to find the answer. 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // It's a lot quicker than actually dividing since we know 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // the answer will be between 0 and 10 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project U = 0; 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long remainder; 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 3; i >= 0; i--) { 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project remainder = R - Si[i]; 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (remainder >= 0) { 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project R = remainder; 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project U += 1 << i; 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project low = R < M; // was M_minus 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project high = R + M > S; // was M_plus 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (low || high) 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project R = R * 10; 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project M = M * 10; 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uArray[setCount++] = U; 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (low && !high) 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uArray[setCount++] = U; 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else if (high && !low) 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uArray[setCount++] = U + 1; 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else if ((R << 1) < S) 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uArray[setCount++] = U; 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uArray[setCount++] = U + 1; 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 299