source: src/main/java/agents/org/apache/commons/lang/NumberUtils.java

Last change on this file was 127, checked in by Wouter Pasman, 6 years ago

#41 ROLL BACK of rev.126 . So this version is equal to rev. 125

File size: 24.6 KB
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17package agents.org.apache.commons.lang;
18
19import java.math.BigDecimal;
20import java.math.BigInteger;
21
22/**
23 * <p>Provides extra functionality for Java Number classes.</p>
24 *
25 * @author Apache Software Foundation
26 * @author <a href="mailto:rand_mcneely@yahoo.com">Rand McNeely</a>
27 * @author <a href="mailto:steve.downey@netfolio.com">Steve Downey</a>
28 * @author Eric Pugh
29 * @author Phil Steitz
30 * @since 1.0
31 * @version $Id: NumberUtils.java 905636 2010-02-02 14:03:32Z niallp $
32 *
33 * @deprecated Moved to org.apache.commons.lang.math.
34 * Class will be removed in Commons Lang 3.0.
35 */
36public final class NumberUtils {
37 // DEPRECATED CLASS !!!
38
39 /**
40 * <p><code>NumberUtils</code> instances should NOT be constructed in standard programming.
41 * Instead, the class should be used as <code>NumberUtils.stringToInt("6");</code>.</p>
42 *
43 * <p>This constructor is public to permit tools that require a JavaBean instance
44 * to operate.</p>
45 */
46 public NumberUtils() {
47 super();
48 }
49
50 //--------------------------------------------------------------------
51
52 /**
53 * <p>Convert a <code>String</code> to an <code>int</code>, returning
54 * <code>zero</code> if the conversion fails.</p>
55 *
56 * @param str the string to convert
57 * @return the int represented by the string, or <code>zero</code> if
58 * conversion fails
59 */
60 public static int stringToInt(String str) {
61 return stringToInt(str, 0);
62 }
63
64 /**
65 * <p>Convert a <code>String</code> to an <code>int</code>, returning a
66 * default value if the conversion fails.</p>
67 *
68 * @param str the string to convert
69 * @param defaultValue the default value
70 * @return the int represented by the string, or the default if conversion fails
71 */
72 public static int stringToInt(String str, int defaultValue) {
73 try {
74 return Integer.parseInt(str);
75 } catch (NumberFormatException nfe) {
76 return defaultValue;
77 }
78 }
79
80 //--------------------------------------------------------------------
81
82 // must handle Long, Float, Integer, Float, Short,
83 // BigDecimal, BigInteger and Byte
84 // useful methods:
85 // Byte.decode(String)
86 // Byte.valueOf(String,int radix)
87 // Byte.valueOf(String)
88 // Double.valueOf(String)
89 // Float.valueOf(String)
90 // new Float(String)
91 // Integer.valueOf(String,int radix)
92 // Integer.valueOf(String)
93 // Integer.decode(String)
94 // Integer.getInteger(String)
95 // Integer.getInteger(String,int val)
96 // Integer.getInteger(String,Integer val)
97 // new Integer(String)
98 // new Double(String)
99 // new Byte(String)
100 // new Long(String)
101 // Long.getLong(String)
102 // Long.getLong(String,int)
103 // Long.getLong(String,Integer)
104 // Long.valueOf(String,int)
105 // Long.valueOf(String)
106 // new Short(String)
107 // Short.decode(String)
108 // Short.valueOf(String,int)
109 // Short.valueOf(String)
110 // new BigDecimal(String)
111 // new BigInteger(String)
112 // new BigInteger(String,int radix)
113 // Possible inputs:
114 // 45 45.5 45E7 4.5E7 Hex Oct Binary xxxF xxxD xxxf xxxd
115 // plus minus everything. Prolly more. A lot are not separable.
116
117 /**
118 * <p>Turns a string value into a java.lang.Number.</p>
119 *
120 * <p>First, the value is examined for a type qualifier on the end
121 * (<code>'f','F','d','D','l','L'</code>). If it is found, it starts
122 * trying to create successively larger types from the type specified
123 * until one is found that can hold the value.</p>
124 *
125 * <p>If a type specifier is not found, it will check for a decimal point
126 * and then try successively larger types from <code>Integer</code> to
127 * <code>BigInteger</code> and from <code>Float</code> to
128 * <code>BigDecimal</code>.</p>
129 *
130 * <p>If the string starts with <code>0x</code> or <code>-0x</code>, it
131 * will be interpreted as a hexadecimal integer. Values with leading
132 * <code>0</code>'s will not be interpreted as octal.</p>
133 *
134 * @param val String containing a number
135 * @return Number created from the string
136 * @throws NumberFormatException if the value cannot be converted
137 */
138 public static Number createNumber(String val) throws NumberFormatException {
139 if (val == null) {
140 return null;
141 }
142 if (val.length() == 0) {
143 throw new NumberFormatException("\"\" is not a valid number.");
144 }
145 if (val.length() == 1 && !Character.isDigit(val.charAt(0))) {
146 throw new NumberFormatException(val + " is not a valid number.");
147 }
148 if (val.startsWith("--")) {
149 // this is protection for poorness in java.lang.BigDecimal.
150 // it accepts this as a legal value, but it does not appear
151 // to be in specification of class. OS X Java parses it to
152 // a wrong value.
153 return null;
154 }
155 if (val.startsWith("0x") || val.startsWith("-0x")) {
156 return createInteger(val);
157 }
158 char lastChar = val.charAt(val.length() - 1);
159 String mant;
160 String dec;
161 String exp;
162 int decPos = val.indexOf('.');
163 int expPos = val.indexOf('e') + val.indexOf('E') + 1;
164
165 if (decPos > -1) {
166
167 if (expPos > -1) {
168 if (expPos < decPos) {
169 throw new NumberFormatException(val + " is not a valid number.");
170 }
171 dec = val.substring(decPos + 1, expPos);
172 } else {
173 dec = val.substring(decPos + 1);
174 }
175 mant = val.substring(0, decPos);
176 } else {
177 if (expPos > -1) {
178 mant = val.substring(0, expPos);
179 } else {
180 mant = val;
181 }
182 dec = null;
183 }
184 if (!Character.isDigit(lastChar)) {
185 if (expPos > -1 && expPos < val.length() - 1) {
186 exp = val.substring(expPos + 1, val.length() - 1);
187 } else {
188 exp = null;
189 }
190 //Requesting a specific type..
191 String numeric = val.substring(0, val.length() - 1);
192 boolean allZeros = isAllZeros(mant) && isAllZeros(exp);
193 switch (lastChar) {
194 case 'l' :
195 case 'L' :
196 if (dec == null
197 && exp == null
198 && (numeric.charAt(0) == '-' && isDigits(numeric.substring(1)) || isDigits(numeric))) {
199 try {
200 return createLong(numeric);
201 } catch (NumberFormatException nfe) {
202 //Too big for a long
203 }
204 return createBigInteger(numeric);
205
206 }
207 throw new NumberFormatException(val + " is not a valid number.");
208 case 'f' :
209 case 'F' :
210 try {
211 Float f = NumberUtils.createFloat(numeric);
212 if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) {
213 //If it's too big for a float or the float value = 0 and the string
214 //has non-zeros in it, then float does not have the precision we want
215 return f;
216 }
217
218 } catch (NumberFormatException e) {
219 // ignore the bad number
220 }
221 //$FALL-THROUGH$
222 case 'd' :
223 case 'D' :
224 try {
225 Double d = NumberUtils.createDouble(numeric);
226 if (!(d.isInfinite() || (d.floatValue() == 0.0D && !allZeros))) {
227 return d;
228 }
229 } catch (NumberFormatException nfe) {
230 // empty catch
231 }
232 try {
233 return createBigDecimal(numeric);
234 } catch (NumberFormatException e) {
235 // empty catch
236 }
237 //$FALL-THROUGH$
238 default :
239 throw new NumberFormatException(val + " is not a valid number.");
240
241 }
242 } else {
243 //User doesn't have a preference on the return type, so let's start
244 //small and go from there...
245 if (expPos > -1 && expPos < val.length() - 1) {
246 exp = val.substring(expPos + 1, val.length());
247 } else {
248 exp = null;
249 }
250 if (dec == null && exp == null) {
251 //Must be an int,long,bigint
252 try {
253 return createInteger(val);
254 } catch (NumberFormatException nfe) {
255 // empty catch
256 }
257 try {
258 return createLong(val);
259 } catch (NumberFormatException nfe) {
260 // empty catch
261 }
262 return createBigInteger(val);
263
264 } else {
265 //Must be a float,double,BigDec
266 boolean allZeros = isAllZeros(mant) && isAllZeros(exp);
267 try {
268 Float f = createFloat(val);
269 if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) {
270 return f;
271 }
272 } catch (NumberFormatException nfe) {
273 // empty catch
274 }
275 try {
276 Double d = createDouble(val);
277 if (!(d.isInfinite() || (d.doubleValue() == 0.0D && !allZeros))) {
278 return d;
279 }
280 } catch (NumberFormatException nfe) {
281 // empty catch
282 }
283
284 return createBigDecimal(val);
285
286 }
287
288 }
289 }
290
291 /**
292 * <p>Utility method for {@link #createNumber(java.lang.String)}.</p>
293 *
294 * <p>Returns <code>true</code> if s is <code>null</code>.</p>
295 *
296 * @param s the String to check
297 * @return if it is all zeros or <code>null</code>
298 */
299 private static boolean isAllZeros(String s) {
300 if (s == null) {
301 return true;
302 }
303 for (int i = s.length() - 1; i >= 0; i--) {
304 if (s.charAt(i) != '0') {
305 return false;
306 }
307 }
308 return s.length() > 0;
309 }
310
311 //--------------------------------------------------------------------
312
313 /**
314 * <p>Convert a <code>String</code> to a <code>Float</code>.</p>
315 *
316 * @param val a <code>String</code> to convert
317 * @return converted <code>Float</code>
318 * @throws NumberFormatException if the value cannot be converted
319 */
320 public static Float createFloat(String val) {
321 return Float.valueOf(val);
322 }
323
324 /**
325 * <p>Convert a <code>String</code> to a <code>Double</code>.</p>
326 *
327 * @param val a <code>String</code> to convert
328 * @return converted <code>Double</code>
329 * @throws NumberFormatException if the value cannot be converted
330 */
331 public static Double createDouble(String val) {
332 return Double.valueOf(val);
333 }
334
335 /**
336 * <p>Convert a <code>String</code> to a <code>Integer</code>, handling
337 * hex and octal notations.</p>
338 *
339 * @param val a <code>String</code> to convert
340 * @return converted <code>Integer</code>
341 * @throws NumberFormatException if the value cannot be converted
342 */
343 public static Integer createInteger(String val) {
344 // decode() handles 0xAABD and 0777 (hex and octal) as well.
345 return Integer.decode(val);
346 }
347
348 /**
349 * <p>Convert a <code>String</code> to a <code>Long</code>.</p>
350 *
351 * @param val a <code>String</code> to convert
352 * @return converted <code>Long</code>
353 * @throws NumberFormatException if the value cannot be converted
354 */
355 public static Long createLong(String val) {
356 return Long.valueOf(val);
357 }
358
359 /**
360 * <p>Convert a <code>String</code> to a <code>BigInteger</code>.</p>
361 *
362 * @param val a <code>String</code> to convert
363 * @return converted <code>BigInteger</code>
364 * @throws NumberFormatException if the value cannot be converted
365 */
366 public static BigInteger createBigInteger(String val) {
367 BigInteger bi = new BigInteger(val);
368 return bi;
369 }
370
371 /**
372 * <p>Convert a <code>String</code> to a <code>BigDecimal</code>.</p>
373 *
374 * @param val a <code>String</code> to convert
375 * @return converted <code>BigDecimal</code>
376 * @throws NumberFormatException if the value cannot be converted
377 */
378 public static BigDecimal createBigDecimal(String val) {
379 BigDecimal bd = new BigDecimal(val);
380 return bd;
381 }
382
383 //--------------------------------------------------------------------
384
385 /**
386 * <p>Gets the minimum of three <code>long</code> values.</p>
387 *
388 * @param a value 1
389 * @param b value 2
390 * @param c value 3
391 * @return the smallest of the values
392 */
393 public static long minimum(long a, long b, long c) {
394 if (b < a) {
395 a = b;
396 }
397 if (c < a) {
398 a = c;
399 }
400 return a;
401 }
402
403 /**
404 * <p>Gets the minimum of three <code>int</code> values.</p>
405 *
406 * @param a value 1
407 * @param b value 2
408 * @param c value 3
409 * @return the smallest of the values
410 */
411 public static int minimum(int a, int b, int c) {
412 if (b < a) {
413 a = b;
414 }
415 if (c < a) {
416 a = c;
417 }
418 return a;
419 }
420
421 /**
422 * <p>Gets the maximum of three <code>long</code> values.</p>
423 *
424 * @param a value 1
425 * @param b value 2
426 * @param c value 3
427 * @return the largest of the values
428 */
429 public static long maximum(long a, long b, long c) {
430 if (b > a) {
431 a = b;
432 }
433 if (c > a) {
434 a = c;
435 }
436 return a;
437 }
438
439 /**
440 * <p>Gets the maximum of three <code>int</code> values.</p>
441 *
442 * @param a value 1
443 * @param b value 2
444 * @param c value 3
445 * @return the largest of the values
446 */
447 public static int maximum(int a, int b, int c) {
448 if (b > a) {
449 a = b;
450 }
451 if (c > a) {
452 a = c;
453 }
454 return a;
455 }
456
457 //--------------------------------------------------------------------
458
459 /**
460 * <p>Compares two <code>doubles</code> for order.</p>
461 *
462 * <p>This method is more comprehensive than the standard Java greater
463 * than, less than and equals operators.</p>
464 * <ul>
465 * <li>It returns <code>-1</code> if the first value is less than the second.
466 * <li>It returns <code>+1</code> if the first value is greater than the second.
467 * <li>It returns <code>0</code> if the values are equal.
468 * </ul>
469 *
470 * <p>
471 * The ordering is as follows, largest to smallest:
472 * <ul>
473 * <li>NaN
474 * <li>Positive infinity
475 * <li>Maximum double
476 * <li>Normal positive numbers
477 * <li>+0.0
478 * <li>-0.0
479 * <li>Normal negative numbers
480 * <li>Minimum double (-Double.MAX_VALUE)
481 * <li>Negative infinity
482 * </ul>
483 * </p>
484 *
485 * <p>Comparing <code>NaN</code> with <code>NaN</code> will
486 * return <code>0</code>.</p>
487 *
488 * @param lhs the first <code>double</code>
489 * @param rhs the second <code>double</code>
490 * @return <code>-1</code> if lhs is less, <code>+1</code> if greater,
491 * <code>0</code> if equal to rhs
492 */
493 public static int compare(double lhs, double rhs) {
494 if (lhs < rhs) {
495 return -1;
496 }
497 if (lhs > rhs) {
498 return +1;
499 }
500 // Need to compare bits to handle 0.0 == -0.0 being true
501 // compare should put -0.0 < +0.0
502 // Two NaNs are also == for compare purposes
503 // where NaN == NaN is false
504 long lhsBits = Double.doubleToLongBits(lhs);
505 long rhsBits = Double.doubleToLongBits(rhs);
506 if (lhsBits == rhsBits) {
507 return 0;
508 }
509 // Something exotic! A comparison to NaN or 0.0 vs -0.0
510 // Fortunately NaN's long is > than everything else
511 // Also negzeros bits < poszero
512 // NAN: 9221120237041090560
513 // MAX: 9218868437227405311
514 // NEGZERO: -9223372036854775808
515 if (lhsBits < rhsBits) {
516 return -1;
517 } else {
518 return +1;
519 }
520 }
521
522 /**
523 * <p>Compares two floats for order.</p>
524 *
525 * <p>This method is more comprehensive than the standard Java greater than,
526 * less than and equals operators.</p>
527 * <ul>
528 * <li>It returns <code>-1</code> if the first value is less than the second.
529 * <li>It returns <code>+1</code> if the first value is greater than the second.
530 * <li>It returns <code>0</code> if the values are equal.
531 * </ul>
532 *
533 * <p> The ordering is as follows, largest to smallest:
534 * <ul>
535 * <li>NaN
536 * <li>Positive infinity
537 * <li>Maximum float
538 * <li>Normal positive numbers
539 * <li>+0.0
540 * <li>-0.0
541 * <li>Normal negative numbers
542 * <li>Minimum float (-Float.MAX_VALUE)
543 * <li>Negative infinity
544 * </ul>
545 *
546 * <p>Comparing <code>NaN</code> with <code>NaN</code> will return
547 * <code>0</code>.</p>
548 *
549 * @param lhs the first <code>float</code>
550 * @param rhs the second <code>float</code>
551 * @return <code>-1</code> if lhs is less, <code>+1</code> if greater,
552 * <code>0</code> if equal to rhs
553 */
554 public static int compare(float lhs, float rhs) {
555 if (lhs < rhs) {
556 return -1;
557 }
558 if (lhs > rhs) {
559 return +1;
560 }
561 //Need to compare bits to handle 0.0 == -0.0 being true
562 // compare should put -0.0 < +0.0
563 // Two NaNs are also == for compare purposes
564 // where NaN == NaN is false
565 int lhsBits = Float.floatToIntBits(lhs);
566 int rhsBits = Float.floatToIntBits(rhs);
567 if (lhsBits == rhsBits) {
568 return 0;
569 }
570 //Something exotic! A comparison to NaN or 0.0 vs -0.0
571 //Fortunately NaN's int is > than everything else
572 //Also negzeros bits < poszero
573 //NAN: 2143289344
574 //MAX: 2139095039
575 //NEGZERO: -2147483648
576 if (lhsBits < rhsBits) {
577 return -1;
578 } else {
579 return +1;
580 }
581 }
582
583 //--------------------------------------------------------------------
584
585 /**
586 * <p>Checks whether the <code>String</code> contains only
587 * digit characters.</p>
588 *
589 * <p><code>Null</code> and empty String will return
590 * <code>false</code>.</p>
591 *
592 * @param str the <code>String</code> to check
593 * @return <code>true</code> if str contains only unicode numeric
594 */
595 public static boolean isDigits(String str) {
596 if ((str == null) || (str.length() == 0)) {
597 return false;
598 }
599 for (int i = 0; i < str.length(); i++) {
600 if (!Character.isDigit(str.charAt(i))) {
601 return false;
602 }
603 }
604 return true;
605 }
606
607 /**
608 * <p>Checks whether the String a valid Java number.</p>
609 *
610 * <p>Valid numbers include hexadecimal marked with the <code>0x</code>
611 * qualifier, scientific notation and numbers marked with a type
612 * qualifier (e.g. 123L).</p>
613 *
614 * <p><code>Null</code> and empty String will return
615 * <code>false</code>.</p>
616 *
617 * @param str the <code>String</code> to check
618 * @return <code>true</code> if the string is a correctly formatted number
619 */
620 public static boolean isNumber(String str) {
621 if (StringUtils.isEmpty(str)) {
622 return false;
623 }
624 char[] chars = str.toCharArray();
625 int sz = chars.length;
626 boolean hasExp = false;
627 boolean hasDecPoint = false;
628 boolean allowSigns = false;
629 boolean foundDigit = false;
630 // deal with any possible sign up front
631 int start = (chars[0] == '-') ? 1 : 0;
632 if (sz > start + 1) {
633 if (chars[start] == '0' && chars[start + 1] == 'x') {
634 int i = start + 2;
635 if (i == sz) {
636 return false; // str == "0x"
637 }
638 // checking hex (it can't be anything else)
639 for (; i < chars.length; i++) {
640 if ((chars[i] < '0' || chars[i] > '9')
641 && (chars[i] < 'a' || chars[i] > 'f')
642 && (chars[i] < 'A' || chars[i] > 'F')) {
643 return false;
644 }
645 }
646 return true;
647 }
648 }
649 sz--; // don't want to loop to the last char, check it afterwords
650 // for type qualifiers
651 int i = start;
652 // loop to the next to last char or to the last char if we need another digit to
653 // make a valid number (e.g. chars[0..5] = "1234E")
654 while (i < sz || (i < sz + 1 && allowSigns && !foundDigit)) {
655 if (chars[i] >= '0' && chars[i] <= '9') {
656 foundDigit = true;
657 allowSigns = false;
658
659 } else if (chars[i] == '.') {
660 if (hasDecPoint || hasExp) {
661 // two decimal points or dec in exponent
662 return false;
663 }
664 hasDecPoint = true;
665 } else if (chars[i] == 'e' || chars[i] == 'E') {
666 // we've already taken care of hex.
667 if (hasExp) {
668 // two E's
669 return false;
670 }
671 if (!foundDigit) {
672 return false;
673 }
674 hasExp = true;
675 allowSigns = true;
676 } else if (chars[i] == '+' || chars[i] == '-') {
677 if (!allowSigns) {
678 return false;
679 }
680 allowSigns = false;
681 foundDigit = false; // we need a digit after the E
682 } else {
683 return false;
684 }
685 i++;
686 }
687 if (i < chars.length) {
688 if (chars[i] >= '0' && chars[i] <= '9') {
689 // no type qualifier, OK
690 return true;
691 }
692 if (chars[i] == 'e' || chars[i] == 'E') {
693 // can't have an E at the last byte
694 return false;
695 }
696 if (!allowSigns
697 && (chars[i] == 'd'
698 || chars[i] == 'D'
699 || chars[i] == 'f'
700 || chars[i] == 'F')) {
701 return foundDigit;
702 }
703 if (chars[i] == 'l'
704 || chars[i] == 'L') {
705 // not allowing L with an exponent
706 return foundDigit && !hasExp;
707 }
708 // last character is illegal
709 return false;
710 }
711 // allowSigns is true iff the val ends in 'E'
712 // found digit it to make sure weird stuff like '.' and '1E-' doesn't pass
713 return !allowSigns && foundDigit;
714 }
715}
Note: See TracBrowser for help on using the repository browser.