114 * Converts a <code>String</code> to a single precision floating point value.
115 *
116 * @param s The <code>String</code> to convert.
117 * @return The single precision value.
118 * @throws NumberFormatException If the <code>String</code> does not
119 * represent a properly formatted single precision value.
120 */
121 public static float parseFloat(String s) throws NumberFormatException {
122 return readJavaFormatString(s).floatValue();
123 }
124
125 /**
126 * A converter which can process single or double precision floating point
127 * values into an ASCII <code>String</code> representation.
128 */
129 public interface BinaryToASCIIConverter {
130 /**
131 * Converts a floating point value into an ASCII <code>String</code>.
132 * @return The value converted to a <code>String</code>.
133 */
134 public String toJavaFormatString();
135
136 /**
137 * Appends a floating point value to an <code>Appendable</code>.
138 * @param buf The <code>Appendable</code> to receive the value.
139 */
140 public void appendTo(Appendable buf);
141
142 /**
143 * Retrieves the decimal exponent most closely corresponding to this value.
144 * @return The decimal exponent.
145 */
146 public int getDecimalExponent();
147
148 /**
149 * Retrieves the value as an array of digits.
150 * @param digits The digit array.
151 * @return The number of valid digits copied into the array.
152 */
153 public int getDigits(char[] digits);
154
155 /**
156 * Indicates the sign of the value.
157 * @return {@code value < 0.0}.
158 */
159 public boolean isNegative();
160
161 /**
162 * Indicates whether the value is either infinite or not a number.
163 *
164 * @return <code>true</code> if and only if the value is <code>NaN</code>
165 * or infinite.
166 */
167 public boolean isExceptional();
168
169 /**
170 * Indicates whether the value was rounded up during the binary to ASCII
171 * conversion.
172 *
173 * @return <code>true</code> if and only if the value was rounded up.
174 */
175 public boolean digitsRoundedUp();
176
177 /**
178 * Indicates whether the binary to ASCII conversion was exact.
179 *
180 * @return <code>true</code> if any only if the conversion was exact.
181 */
182 public boolean decimalDigitsExact();
183 }
184
185 /**
186 * A <code>BinaryToASCIIConverter</code> which represents <code>NaN</code>
187 * and infinite values.
188 */
189 private static class ExceptionalBinaryToASCIIBuffer implements BinaryToASCIIConverter {
190 private final String image;
191 private boolean isNegative;
192
193 public ExceptionalBinaryToASCIIBuffer(String image, boolean isNegative) {
194 this.image = image;
195 this.isNegative = isNegative;
196 }
197
198 @Override
199 public String toJavaFormatString() {
200 return image;
201 }
202
304
305 @Override
306 public void appendTo(Appendable buf) {
307 int len = getChars(buffer);
308 if (buf instanceof StringBuilder) {
309 ((StringBuilder) buf).append(buffer, 0, len);
310 } else if (buf instanceof StringBuffer) {
311 ((StringBuffer) buf).append(buffer, 0, len);
312 } else {
313 assert false;
314 }
315 }
316
317 @Override
318 public int getDecimalExponent() {
319 return decExponent;
320 }
321
322 @Override
323 public int getDigits(char[] digits) {
324 System.arraycopy(this.digits,firstDigitIndex,digits,0,this.nDigits);
325 return this.nDigits;
326 }
327
328 @Override
329 public boolean isNegative() {
330 return isNegative;
331 }
332
333 @Override
334 public boolean isExceptional() {
335 return false;
336 }
337
338 @Override
339 public boolean digitsRoundedUp() {
340 return decimalDigitsRoundedUp;
341 }
342
343 @Override
344 public boolean decimalDigitsExact() {
832 } else { //if (exponent >= 52)
833 return (int)d;
834 }
835 }
836
837 private static int insignificantDigits(int insignificant) {
838 int i;
839 for ( i = 0; insignificant >= 10L; i++ ) {
840 insignificant /= 10L;
841 }
842 return i;
843 }
844
845 /**
846 * Calculates
847 * <pre>
848 * insignificantDigitsForPow2(v) == insignificantDigits(1L<<v)
849 * </pre>
850 */
851 private static int insignificantDigitsForPow2(int p2) {
852 if(p2>1 && p2 < insignificantDigitsNumber.length) {
853 return insignificantDigitsNumber[p2];
854 }
855 return 0;
856 }
857
858 /**
859 * If insignificant==(1L << ixd)
860 * i = insignificantDigitsNumber[idx] is the same as:
861 * int i;
862 * for ( i = 0; insignificant >= 10L; i++ )
863 * insignificant /= 10L;
864 */
865 private static int[] insignificantDigitsNumber = {
866 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3,
867 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7,
868 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 11, 11, 11,
869 12, 12, 12, 12, 13, 13, 13, 14, 14, 14,
870 15, 15, 15, 15, 16, 16, 16, 17, 17, 17,
871 18, 18, 18, 19
872 };
873
874 // approximately ceil( log2( long5pow[i] ) )
875 private static final int[] N_5_BITS = {
876 0,
877 3,
878 5,
879 7,
880 10,
881 12,
882 14,
883 17,
884 19,
885 21,
1856 return A2BC_NOT_A_NUMBER;
1857 }
1858 // something went wrong, throw exception
1859 break parseNumber;
1860 } else if(c == 'I') { // Check for Infinity strings
1861 if((len-i)==INFINITY_LENGTH && in.indexOf(INFINITY_REP,i)==i) {
1862 return isNegative? A2BC_NEGATIVE_INFINITY : A2BC_POSITIVE_INFINITY;
1863 }
1864 // something went wrong, throw exception
1865 break parseNumber;
1866 } else if (c == '0') { // check for hexadecimal floating-point number
1867 if (len > i+1 ) {
1868 char ch = in.charAt(i+1);
1869 if (ch == 'x' || ch == 'X' ) { // possible hex string
1870 return parseHexString(in);
1871 }
1872 }
1873 } // look for and process decimal floating-point string
1874
1875 char[] digits = new char[ len ];
1876 int nDigits= 0;
1877 boolean decSeen = false;
1878 int decPt = 0;
1879 int nLeadZero = 0;
1880 int nTrailZero= 0;
1881
1882 skipLeadingZerosLoop:
1883 while (i < len) {
1884 c = in.charAt(i);
1885 if (c == '0') {
1886 nLeadZero++;
1887 } else if (c == '.') {
1888 if (decSeen) {
1889 // already saw one ., this is the 2nd.
1890 throw new NumberFormatException("multiple points");
1891 }
1892 decPt = i;
1893 if (signSeen) {
1894 decPt -= 1;
1895 }
1896 decSeen = true;
1897 } else {
1898 break skipLeadingZerosLoop;
1899 }
1900 i++;
2120 //
2121 // There are a number of significand scenarios to consider;
2122 // letters are used in indicate nonzero digits:
2123 //
2124 // 1. 000xxxx => x.xxx normalized
2125 // increase exponent by (number of x's - 1)*4
2126 //
2127 // 2. 000xxx.yyyy => x.xxyyyy normalized
2128 // increase exponent by (number of x's - 1)*4
2129 //
2130 // 3. .000yyy => y.yy normalized
2131 // decrease exponent by (number of zeros + 1)*4
2132 //
2133 // 4. 000.00000yyy => y.yy normalized
2134 // decrease exponent by (number of zeros to right of point + 1)*4
2135 //
2136 // If the significand is exactly zero, return a properly
2137 // signed zero.
2138 //
2139
2140 String significandString = null;
2141 int signifLength = 0;
2142 int exponentAdjust = 0;
2143 {
2144 int leftDigits = 0; // number of meaningful digits to
2145 // left of "decimal" point
2146 // (leading zeros stripped)
2147 int rightDigits = 0; // number of digits to right of
2148 // "decimal" point; leading zeros
2149 // must always be accounted for
2150 //
2151 // The significand is made up of either
2152 //
2153 // 1. group 4 entirely (integer portion only)
2154 //
2155 // OR
2156 //
2157 // 2. the fractional portion from group 7 plus any
2158 // (optional) integer portions from group 6.
2159 //
2160 String group4;
2161 if ((group4 = m.group(4)) != null) { // Integer-only significand
2162 // Leading zeros never matter on the integer portion
2229 // - +0.0 -0.0
2230 return isNegative ?
2231 (positiveExponent ? A2BC_NEGATIVE_INFINITY : A2BC_NEGATIVE_ZERO)
2232 : (positiveExponent ? A2BC_POSITIVE_INFINITY : A2BC_POSITIVE_ZERO);
2233
2234 }
2235
2236 long rawExponent =
2237 (positiveExponent ? 1L : -1L) * // exponent sign
2238 unsignedRawExponent; // exponent magnitude
2239
2240 // Calculate partially adjusted exponent
2241 long exponent = rawExponent + exponentAdjust;
2242
2243 // Starting copying non-zero bits into proper position in
2244 // a long; copy explicit bit too; this will be masked
2245 // later for normal values.
2246
2247 boolean round = false;
2248 boolean sticky = false;
2249 int nextShift = 0;
2250 long significand = 0L;
2251 // First iteration is different, since we only copy
2252 // from the leading significand bit; one more exponent
2253 // adjust will be needed...
2254
2255 // IMPORTANT: make leadingDigit a long to avoid
2256 // surprising shift semantics!
2257 long leadingDigit = getHexDigit(significandString, 0);
2258
2259 //
2260 // Left shift the leading digit (53 - (bit position of
2261 // leading 1 in digit)); this sets the top bit of the
2262 // significand to 1. The nextShift value is adjusted
2263 // to take into account the number of bit positions of
2264 // the leadingDigit actually used. Finally, the
2265 // exponent is adjusted to normalize the significand
2266 // as a binary value, not just a hex value.
2267 //
2268 if (leadingDigit == 1) {
2269 significand |= leadingDigit << 52;
2508 //
2509 boolean leastZero = ((significand & 1L) == 0L);
2510 if ((leastZero && round && sticky) ||
2511 ((!leastZero) && round)) {
2512 significand++;
2513 }
2514
2515 double value = isNegative ?
2516 Double.longBitsToDouble(significand | DoubleConsts.SIGN_BIT_MASK) :
2517 Double.longBitsToDouble(significand );
2518
2519 return new PreparedASCIIToBinaryBuffer(value, fValue);
2520 }
2521 }
2522 }
2523
2524 /**
2525 * Returns <code>s</code> with any leading zeros removed.
2526 */
2527 static String stripLeadingZeros(String s) {
2528 // return s.replaceFirst("^0+", "");
2529 if(!s.isEmpty() && s.charAt(0)=='0') {
2530 for(int i=1; i<s.length(); i++) {
2531 if(s.charAt(i)!='0') {
2532 return s.substring(i);
2533 }
2534 }
2535 return "";
2536 }
2537 return s;
2538 }
2539
2540 /**
2541 * Extracts a hexadecimal digit from position <code>position</code>
2542 * of string <code>s</code>.
2543 */
2544 static int getHexDigit(String s, int position) {
2545 int value = Character.digit(s.charAt(position), 16);
2546 if (value <= -1 || value >= 16) {
2547 throw new AssertionError("Unexpected failure of digit conversion of " +
2548 s.charAt(position));
|
114 * Converts a <code>String</code> to a single precision floating point value.
115 *
116 * @param s The <code>String</code> to convert.
117 * @return The single precision value.
118 * @throws NumberFormatException If the <code>String</code> does not
119 * represent a properly formatted single precision value.
120 */
121 public static float parseFloat(String s) throws NumberFormatException {
122 return readJavaFormatString(s).floatValue();
123 }
124
125 /**
126 * A converter which can process single or double precision floating point
127 * values into an ASCII <code>String</code> representation.
128 */
129 public interface BinaryToASCIIConverter {
130 /**
131 * Converts a floating point value into an ASCII <code>String</code>.
132 * @return The value converted to a <code>String</code>.
133 */
134 String toJavaFormatString();
135
136 /**
137 * Appends a floating point value to an <code>Appendable</code>.
138 * @param buf The <code>Appendable</code> to receive the value.
139 */
140 void appendTo(Appendable buf);
141
142 /**
143 * Retrieves the decimal exponent most closely corresponding to this value.
144 * @return The decimal exponent.
145 */
146 int getDecimalExponent();
147
148 /**
149 * Retrieves the value as an array of digits.
150 * @param digits The digit array.
151 * @return The number of valid digits copied into the array.
152 */
153 int getDigits(char[] digits);
154
155 /**
156 * Indicates the sign of the value.
157 * @return {@code value < 0.0}.
158 */
159 boolean isNegative();
160
161 /**
162 * Indicates whether the value is either infinite or not a number.
163 *
164 * @return <code>true</code> if and only if the value is <code>NaN</code>
165 * or infinite.
166 */
167 boolean isExceptional();
168
169 /**
170 * Indicates whether the value was rounded up during the binary to ASCII
171 * conversion.
172 *
173 * @return <code>true</code> if and only if the value was rounded up.
174 */
175 boolean digitsRoundedUp();
176
177 /**
178 * Indicates whether the binary to ASCII conversion was exact.
179 *
180 * @return <code>true</code> if any only if the conversion was exact.
181 */
182 boolean decimalDigitsExact();
183 }
184
185 /**
186 * A <code>BinaryToASCIIConverter</code> which represents <code>NaN</code>
187 * and infinite values.
188 */
189 private static class ExceptionalBinaryToASCIIBuffer implements BinaryToASCIIConverter {
190 private final String image;
191 private boolean isNegative;
192
193 public ExceptionalBinaryToASCIIBuffer(String image, boolean isNegative) {
194 this.image = image;
195 this.isNegative = isNegative;
196 }
197
198 @Override
199 public String toJavaFormatString() {
200 return image;
201 }
202
304
305 @Override
306 public void appendTo(Appendable buf) {
307 int len = getChars(buffer);
308 if (buf instanceof StringBuilder) {
309 ((StringBuilder) buf).append(buffer, 0, len);
310 } else if (buf instanceof StringBuffer) {
311 ((StringBuffer) buf).append(buffer, 0, len);
312 } else {
313 assert false;
314 }
315 }
316
317 @Override
318 public int getDecimalExponent() {
319 return decExponent;
320 }
321
322 @Override
323 public int getDigits(char[] digits) {
324 System.arraycopy(this.digits, firstDigitIndex, digits, 0, this.nDigits);
325 return this.nDigits;
326 }
327
328 @Override
329 public boolean isNegative() {
330 return isNegative;
331 }
332
333 @Override
334 public boolean isExceptional() {
335 return false;
336 }
337
338 @Override
339 public boolean digitsRoundedUp() {
340 return decimalDigitsRoundedUp;
341 }
342
343 @Override
344 public boolean decimalDigitsExact() {
832 } else { //if (exponent >= 52)
833 return (int)d;
834 }
835 }
836
837 private static int insignificantDigits(int insignificant) {
838 int i;
839 for ( i = 0; insignificant >= 10L; i++ ) {
840 insignificant /= 10L;
841 }
842 return i;
843 }
844
845 /**
846 * Calculates
847 * <pre>
848 * insignificantDigitsForPow2(v) == insignificantDigits(1L<<v)
849 * </pre>
850 */
851 private static int insignificantDigitsForPow2(int p2) {
852 if (p2 > 1 && p2 < insignificantDigitsNumber.length) {
853 return insignificantDigitsNumber[p2];
854 }
855 return 0;
856 }
857
858 /**
859 * If insignificant==(1L << ixd)
860 * i = insignificantDigitsNumber[idx] is the same as:
861 * int i;
862 * for ( i = 0; insignificant >= 10L; i++ )
863 * insignificant /= 10L;
864 */
865 private static final int[] insignificantDigitsNumber = {
866 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3,
867 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7,
868 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 11, 11, 11,
869 12, 12, 12, 12, 13, 13, 13, 14, 14, 14,
870 15, 15, 15, 15, 16, 16, 16, 17, 17, 17,
871 18, 18, 18, 19
872 };
873
874 // approximately ceil( log2( long5pow[i] ) )
875 private static final int[] N_5_BITS = {
876 0,
877 3,
878 5,
879 7,
880 10,
881 12,
882 14,
883 17,
884 19,
885 21,
1856 return A2BC_NOT_A_NUMBER;
1857 }
1858 // something went wrong, throw exception
1859 break parseNumber;
1860 } else if(c == 'I') { // Check for Infinity strings
1861 if((len-i)==INFINITY_LENGTH && in.indexOf(INFINITY_REP,i)==i) {
1862 return isNegative? A2BC_NEGATIVE_INFINITY : A2BC_POSITIVE_INFINITY;
1863 }
1864 // something went wrong, throw exception
1865 break parseNumber;
1866 } else if (c == '0') { // check for hexadecimal floating-point number
1867 if (len > i+1 ) {
1868 char ch = in.charAt(i+1);
1869 if (ch == 'x' || ch == 'X' ) { // possible hex string
1870 return parseHexString(in);
1871 }
1872 }
1873 } // look for and process decimal floating-point string
1874
1875 char[] digits = new char[ len ];
1876 boolean decSeen = false;
1877 int nDigits = 0;
1878 int decPt = 0;
1879 int nLeadZero = 0;
1880 int nTrailZero = 0;
1881
1882 skipLeadingZerosLoop:
1883 while (i < len) {
1884 c = in.charAt(i);
1885 if (c == '0') {
1886 nLeadZero++;
1887 } else if (c == '.') {
1888 if (decSeen) {
1889 // already saw one ., this is the 2nd.
1890 throw new NumberFormatException("multiple points");
1891 }
1892 decPt = i;
1893 if (signSeen) {
1894 decPt -= 1;
1895 }
1896 decSeen = true;
1897 } else {
1898 break skipLeadingZerosLoop;
1899 }
1900 i++;
2120 //
2121 // There are a number of significand scenarios to consider;
2122 // letters are used in indicate nonzero digits:
2123 //
2124 // 1. 000xxxx => x.xxx normalized
2125 // increase exponent by (number of x's - 1)*4
2126 //
2127 // 2. 000xxx.yyyy => x.xxyyyy normalized
2128 // increase exponent by (number of x's - 1)*4
2129 //
2130 // 3. .000yyy => y.yy normalized
2131 // decrease exponent by (number of zeros + 1)*4
2132 //
2133 // 4. 000.00000yyy => y.yy normalized
2134 // decrease exponent by (number of zeros to right of point + 1)*4
2135 //
2136 // If the significand is exactly zero, return a properly
2137 // signed zero.
2138 //
2139
2140 String significandString;
2141 int signifLength;
2142 int exponentAdjust;
2143 {
2144 int leftDigits = 0; // number of meaningful digits to
2145 // left of "decimal" point
2146 // (leading zeros stripped)
2147 int rightDigits = 0; // number of digits to right of
2148 // "decimal" point; leading zeros
2149 // must always be accounted for
2150 //
2151 // The significand is made up of either
2152 //
2153 // 1. group 4 entirely (integer portion only)
2154 //
2155 // OR
2156 //
2157 // 2. the fractional portion from group 7 plus any
2158 // (optional) integer portions from group 6.
2159 //
2160 String group4;
2161 if ((group4 = m.group(4)) != null) { // Integer-only significand
2162 // Leading zeros never matter on the integer portion
2229 // - +0.0 -0.0
2230 return isNegative ?
2231 (positiveExponent ? A2BC_NEGATIVE_INFINITY : A2BC_NEGATIVE_ZERO)
2232 : (positiveExponent ? A2BC_POSITIVE_INFINITY : A2BC_POSITIVE_ZERO);
2233
2234 }
2235
2236 long rawExponent =
2237 (positiveExponent ? 1L : -1L) * // exponent sign
2238 unsignedRawExponent; // exponent magnitude
2239
2240 // Calculate partially adjusted exponent
2241 long exponent = rawExponent + exponentAdjust;
2242
2243 // Starting copying non-zero bits into proper position in
2244 // a long; copy explicit bit too; this will be masked
2245 // later for normal values.
2246
2247 boolean round = false;
2248 boolean sticky = false;
2249 int nextShift;
2250 long significand = 0L;
2251 // First iteration is different, since we only copy
2252 // from the leading significand bit; one more exponent
2253 // adjust will be needed...
2254
2255 // IMPORTANT: make leadingDigit a long to avoid
2256 // surprising shift semantics!
2257 long leadingDigit = getHexDigit(significandString, 0);
2258
2259 //
2260 // Left shift the leading digit (53 - (bit position of
2261 // leading 1 in digit)); this sets the top bit of the
2262 // significand to 1. The nextShift value is adjusted
2263 // to take into account the number of bit positions of
2264 // the leadingDigit actually used. Finally, the
2265 // exponent is adjusted to normalize the significand
2266 // as a binary value, not just a hex value.
2267 //
2268 if (leadingDigit == 1) {
2269 significand |= leadingDigit << 52;
2508 //
2509 boolean leastZero = ((significand & 1L) == 0L);
2510 if ((leastZero && round && sticky) ||
2511 ((!leastZero) && round)) {
2512 significand++;
2513 }
2514
2515 double value = isNegative ?
2516 Double.longBitsToDouble(significand | DoubleConsts.SIGN_BIT_MASK) :
2517 Double.longBitsToDouble(significand );
2518
2519 return new PreparedASCIIToBinaryBuffer(value, fValue);
2520 }
2521 }
2522 }
2523
2524 /**
2525 * Returns <code>s</code> with any leading zeros removed.
2526 */
2527 static String stripLeadingZeros(String s) {
2528 if(!s.isEmpty() && s.charAt(0)=='0') {
2529 for(int i=1; i<s.length(); i++) {
2530 if(s.charAt(i)!='0') {
2531 return s.substring(i);
2532 }
2533 }
2534 return "";
2535 }
2536 return s;
2537 }
2538
2539 /**
2540 * Extracts a hexadecimal digit from position <code>position</code>
2541 * of string <code>s</code>.
2542 */
2543 static int getHexDigit(String s, int position) {
2544 int value = Character.digit(s.charAt(position), 16);
2545 if (value <= -1 || value >= 16) {
2546 throw new AssertionError("Unexpected failure of digit conversion of " +
2547 s.charAt(position));
|