View Javadoc
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   */
17  package org.apache.commons.lang3.math;
18  
19  import java.lang.reflect.Array;
20  import java.math.BigDecimal;
21  import java.math.BigInteger;
22  
23  import org.apache.commons.lang3.StringUtils;
24  import org.apache.commons.lang3.Validate;
25  
26  /**
27   * <p>Provides extra functionality for Java Number classes.</p>
28   *
29   * @since 2.0
30   */
31  public class NumberUtils {
32      
33      /** Reusable Long constant for zero. */
34      public static final Long LONG_ZERO = Long.valueOf(0L);
35      /** Reusable Long constant for one. */
36      public static final Long LONG_ONE = Long.valueOf(1L);
37      /** Reusable Long constant for minus one. */
38      public static final Long LONG_MINUS_ONE = Long.valueOf(-1L);
39      /** Reusable Integer constant for zero. */
40      public static final Integer INTEGER_ZERO = Integer.valueOf(0);
41      /** Reusable Integer constant for one. */
42      public static final Integer INTEGER_ONE = Integer.valueOf(1);
43      /** Reusable Integer constant for minus one. */
44      public static final Integer INTEGER_MINUS_ONE = Integer.valueOf(-1);
45      /** Reusable Short constant for zero. */
46      public static final Short SHORT_ZERO = Short.valueOf((short) 0);
47      /** Reusable Short constant for one. */
48      public static final Short SHORT_ONE = Short.valueOf((short) 1);
49      /** Reusable Short constant for minus one. */
50      public static final Short SHORT_MINUS_ONE = Short.valueOf((short) -1);
51      /** Reusable Byte constant for zero. */
52      public static final Byte BYTE_ZERO = Byte.valueOf((byte) 0);
53      /** Reusable Byte constant for one. */
54      public static final Byte BYTE_ONE = Byte.valueOf((byte) 1);
55      /** Reusable Byte constant for minus one. */
56      public static final Byte BYTE_MINUS_ONE = Byte.valueOf((byte) -1);
57      /** Reusable Double constant for zero. */
58      public static final Double DOUBLE_ZERO = Double.valueOf(0.0d);
59      /** Reusable Double constant for one. */
60      public static final Double DOUBLE_ONE = Double.valueOf(1.0d);
61      /** Reusable Double constant for minus one. */
62      public static final Double DOUBLE_MINUS_ONE = Double.valueOf(-1.0d);
63      /** Reusable Float constant for zero. */
64      public static final Float FLOAT_ZERO = Float.valueOf(0.0f);
65      /** Reusable Float constant for one. */
66      public static final Float FLOAT_ONE = Float.valueOf(1.0f);
67      /** Reusable Float constant for minus one. */
68      public static final Float FLOAT_MINUS_ONE = Float.valueOf(-1.0f);
69  
70      /**
71       * <p><code>NumberUtils</code> instances should NOT be constructed in standard programming.
72       * Instead, the class should be used as <code>NumberUtils.toInt("6");</code>.</p>
73       *
74       * <p>This constructor is public to permit tools that require a JavaBean instance
75       * to operate.</p>
76       */
77      public NumberUtils() {
78          super();
79      }
80  
81      //-----------------------------------------------------------------------
82      /**
83       * <p>Convert a <code>String</code> to an <code>int</code>, returning
84       * <code>zero</code> if the conversion fails.</p>
85       *
86       * <p>If the string is <code>null</code>, <code>zero</code> is returned.</p>
87       *
88       * <pre>
89       *   NumberUtils.toInt(null) = 0
90       *   NumberUtils.toInt("")   = 0
91       *   NumberUtils.toInt("1")  = 1
92       * </pre>
93       *
94       * @param str  the string to convert, may be null
95       * @return the int represented by the string, or <code>zero</code> if
96       *  conversion fails
97       * @since 2.1
98       */
99      public static int toInt(final String str) {
100         return toInt(str, 0);
101     }
102 
103     /**
104      * <p>Convert a <code>String</code> to an <code>int</code>, returning a
105      * default value if the conversion fails.</p>
106      *
107      * <p>If the string is <code>null</code>, the default value is returned.</p>
108      *
109      * <pre>
110      *   NumberUtils.toInt(null, 1) = 1
111      *   NumberUtils.toInt("", 1)   = 1
112      *   NumberUtils.toInt("1", 0)  = 1
113      * </pre>
114      *
115      * @param str  the string to convert, may be null
116      * @param defaultValue  the default value
117      * @return the int represented by the string, or the default if conversion fails
118      * @since 2.1
119      */
120     public static int toInt(final String str, final int defaultValue) {
121         if(str == null) {
122             return defaultValue;
123         }
124         try {
125             return Integer.parseInt(str);
126         } catch (final NumberFormatException nfe) {
127             return defaultValue;
128         }
129     }
130 
131     /**
132      * <p>Convert a <code>String</code> to a <code>long</code>, returning
133      * <code>zero</code> if the conversion fails.</p>
134      *
135      * <p>If the string is <code>null</code>, <code>zero</code> is returned.</p>
136      *
137      * <pre>
138      *   NumberUtils.toLong(null) = 0L
139      *   NumberUtils.toLong("")   = 0L
140      *   NumberUtils.toLong("1")  = 1L
141      * </pre>
142      *
143      * @param str  the string to convert, may be null
144      * @return the long represented by the string, or <code>0</code> if
145      *  conversion fails
146      * @since 2.1
147      */
148     public static long toLong(final String str) {
149         return toLong(str, 0L);
150     }
151 
152     /**
153      * <p>Convert a <code>String</code> to a <code>long</code>, returning a
154      * default value if the conversion fails.</p>
155      *
156      * <p>If the string is <code>null</code>, the default value is returned.</p>
157      *
158      * <pre>
159      *   NumberUtils.toLong(null, 1L) = 1L
160      *   NumberUtils.toLong("", 1L)   = 1L
161      *   NumberUtils.toLong("1", 0L)  = 1L
162      * </pre>
163      *
164      * @param str  the string to convert, may be null
165      * @param defaultValue  the default value
166      * @return the long represented by the string, or the default if conversion fails
167      * @since 2.1
168      */
169     public static long toLong(final String str, final long defaultValue) {
170         if (str == null) {
171             return defaultValue;
172         }
173         try {
174             return Long.parseLong(str);
175         } catch (final NumberFormatException nfe) {
176             return defaultValue;
177         }
178     }
179 
180     /**
181      * <p>Convert a <code>String</code> to a <code>float</code>, returning
182      * <code>0.0f</code> if the conversion fails.</p>
183      *
184      * <p>If the string <code>str</code> is <code>null</code>,
185      * <code>0.0f</code> is returned.</p>
186      *
187      * <pre>
188      *   NumberUtils.toFloat(null)   = 0.0f
189      *   NumberUtils.toFloat("")     = 0.0f
190      *   NumberUtils.toFloat("1.5")  = 1.5f
191      * </pre>
192      *
193      * @param str the string to convert, may be <code>null</code>
194      * @return the float represented by the string, or <code>0.0f</code>
195      *  if conversion fails
196      * @since 2.1
197      */
198     public static float toFloat(final String str) {
199         return toFloat(str, 0.0f);
200     }
201 
202     /**
203      * <p>Convert a <code>String</code> to a <code>float</code>, returning a
204      * default value if the conversion fails.</p>
205      *
206      * <p>If the string <code>str</code> is <code>null</code>, the default
207      * value is returned.</p>
208      *
209      * <pre>
210      *   NumberUtils.toFloat(null, 1.1f)   = 1.0f
211      *   NumberUtils.toFloat("", 1.1f)     = 1.1f
212      *   NumberUtils.toFloat("1.5", 0.0f)  = 1.5f
213      * </pre>
214      *
215      * @param str the string to convert, may be <code>null</code>
216      * @param defaultValue the default value
217      * @return the float represented by the string, or defaultValue
218      *  if conversion fails
219      * @since 2.1
220      */
221     public static float toFloat(final String str, final float defaultValue) {
222       if (str == null) {
223           return defaultValue;
224       }     
225       try {
226           return Float.parseFloat(str);
227       } catch (final NumberFormatException nfe) {
228           return defaultValue;
229       }
230     }
231 
232     /**
233      * <p>Convert a <code>String</code> to a <code>double</code>, returning
234      * <code>0.0d</code> if the conversion fails.</p>
235      *
236      * <p>If the string <code>str</code> is <code>null</code>,
237      * <code>0.0d</code> is returned.</p>
238      *
239      * <pre>
240      *   NumberUtils.toDouble(null)   = 0.0d
241      *   NumberUtils.toDouble("")     = 0.0d
242      *   NumberUtils.toDouble("1.5")  = 1.5d
243      * </pre>
244      *
245      * @param str the string to convert, may be <code>null</code>
246      * @return the double represented by the string, or <code>0.0d</code>
247      *  if conversion fails
248      * @since 2.1
249      */
250     public static double toDouble(final String str) {
251         return toDouble(str, 0.0d);
252     }
253 
254     /**
255      * <p>Convert a <code>String</code> to a <code>double</code>, returning a
256      * default value if the conversion fails.</p>
257      *
258      * <p>If the string <code>str</code> is <code>null</code>, the default
259      * value is returned.</p>
260      *
261      * <pre>
262      *   NumberUtils.toDouble(null, 1.1d)   = 1.1d
263      *   NumberUtils.toDouble("", 1.1d)     = 1.1d
264      *   NumberUtils.toDouble("1.5", 0.0d)  = 1.5d
265      * </pre>
266      *
267      * @param str the string to convert, may be <code>null</code>
268      * @param defaultValue the default value
269      * @return the double represented by the string, or defaultValue
270      *  if conversion fails
271      * @since 2.1
272      */
273     public static double toDouble(final String str, final double defaultValue) {
274       if (str == null) {
275           return defaultValue;
276       }
277       try {
278           return Double.parseDouble(str);
279       } catch (final NumberFormatException nfe) {
280           return defaultValue;
281       }
282     }
283 
284      //-----------------------------------------------------------------------
285      /**
286      * <p>Convert a <code>String</code> to a <code>byte</code>, returning
287      * <code>zero</code> if the conversion fails.</p>
288      *
289      * <p>If the string is <code>null</code>, <code>zero</code> is returned.</p>
290      *
291      * <pre>
292      *   NumberUtils.toByte(null) = 0
293      *   NumberUtils.toByte("")   = 0
294      *   NumberUtils.toByte("1")  = 1
295      * </pre>
296      *
297      * @param str  the string to convert, may be null
298      * @return the byte represented by the string, or <code>zero</code> if
299      *  conversion fails
300      * @since 2.5
301      */
302     public static byte toByte(final String str) {
303         return toByte(str, (byte) 0);
304     }
305 
306     /**
307      * <p>Convert a <code>String</code> to a <code>byte</code>, returning a
308      * default value if the conversion fails.</p>
309      *
310      * <p>If the string is <code>null</code>, the default value is returned.</p>
311      *
312      * <pre>
313      *   NumberUtils.toByte(null, 1) = 1
314      *   NumberUtils.toByte("", 1)   = 1
315      *   NumberUtils.toByte("1", 0)  = 1
316      * </pre>
317      *
318      * @param str  the string to convert, may be null
319      * @param defaultValue  the default value
320      * @return the byte represented by the string, or the default if conversion fails
321      * @since 2.5
322      */
323     public static byte toByte(final String str, final byte defaultValue) {
324         if(str == null) {
325             return defaultValue;
326         }
327         try {
328             return Byte.parseByte(str);
329         } catch (final NumberFormatException nfe) {
330             return defaultValue;
331         }
332     }
333 
334     /**
335      * <p>Convert a <code>String</code> to a <code>short</code>, returning
336      * <code>zero</code> if the conversion fails.</p>
337      *
338      * <p>If the string is <code>null</code>, <code>zero</code> is returned.</p>
339      *
340      * <pre>
341      *   NumberUtils.toShort(null) = 0
342      *   NumberUtils.toShort("")   = 0
343      *   NumberUtils.toShort("1")  = 1
344      * </pre>
345      *
346      * @param str  the string to convert, may be null
347      * @return the short represented by the string, or <code>zero</code> if
348      *  conversion fails
349      * @since 2.5
350      */
351     public static short toShort(final String str) {
352         return toShort(str, (short) 0);
353     }
354 
355     /**
356      * <p>Convert a <code>String</code> to an <code>short</code>, returning a
357      * default value if the conversion fails.</p>
358      *
359      * <p>If the string is <code>null</code>, the default value is returned.</p>
360      *
361      * <pre>
362      *   NumberUtils.toShort(null, 1) = 1
363      *   NumberUtils.toShort("", 1)   = 1
364      *   NumberUtils.toShort("1", 0)  = 1
365      * </pre>
366      *
367      * @param str  the string to convert, may be null
368      * @param defaultValue  the default value
369      * @return the short represented by the string, or the default if conversion fails
370      * @since 2.5
371      */
372     public static short toShort(final String str, final short defaultValue) {
373         if(str == null) {
374             return defaultValue;
375         }
376         try {
377             return Short.parseShort(str);
378         } catch (final NumberFormatException nfe) {
379             return defaultValue;
380         }
381     }
382 
383     //-----------------------------------------------------------------------
384     // must handle Long, Float, Integer, Float, Short,
385     //                  BigDecimal, BigInteger and Byte
386     // useful methods:
387     // Byte.decode(String)
388     // Byte.valueOf(String,int radix)
389     // Byte.valueOf(String)
390     // Double.valueOf(String)
391     // Float.valueOf(String)
392     // Float.valueOf(String)
393     // Integer.valueOf(String,int radix)
394     // Integer.valueOf(String)
395     // Integer.decode(String)
396     // Integer.getInteger(String)
397     // Integer.getInteger(String,int val)
398     // Integer.getInteger(String,Integer val)
399     // Integer.valueOf(String)
400     // Double.valueOf(String)
401     // new Byte(String)
402     // Long.valueOf(String)
403     // Long.getLong(String)
404     // Long.getLong(String,int)
405     // Long.getLong(String,Integer)
406     // Long.valueOf(String,int)
407     // Long.valueOf(String)
408     // Short.valueOf(String)
409     // Short.decode(String)
410     // Short.valueOf(String,int)
411     // Short.valueOf(String)
412     // new BigDecimal(String)
413     // new BigInteger(String)
414     // new BigInteger(String,int radix)
415     // Possible inputs:
416     // 45 45.5 45E7 4.5E7 Hex Oct Binary xxxF xxxD xxxf xxxd
417     // plus minus everything. Prolly more. A lot are not separable.
418 
419     /**
420      * <p>Turns a string value into a java.lang.Number.</p>
421      *
422      * <p>If the string starts with {@code 0x} or {@code -0x} (lower or upper case) or {@code #} or {@code -#}, it
423      * will be interpreted as a hexadecimal Integer - or Long, if the number of digits after the
424      * prefix is more than 8 - or BigInteger if there are more than 16 digits.
425      * </p>
426      * <p>Then, the value is examined for a type qualifier on the end, i.e. one of
427      * <code>'f','F','d','D','l','L'</code>.  If it is found, it starts 
428      * trying to create successively larger types from the type specified
429      * until one is found that can represent the value.</p>
430      *
431      * <p>If a type specifier is not found, it will check for a decimal point
432      * and then try successively larger types from <code>Integer</code> to
433      * <code>BigInteger</code> and from <code>Float</code> to
434     * <code>BigDecimal</code>.</p>
435     * 
436      * <p>
437      * Integral values with a leading {@code 0} will be interpreted as octal; the returned number will
438      * be Integer, Long or BigDecimal as appropriate.
439      * </p>
440      *
441      * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
442      *
443      * <p>This method does not trim the input string, i.e., strings with leading
444      * or trailing spaces will generate NumberFormatExceptions.</p>
445      *
446      * @param str  String containing a number, may be null
447      * @return Number created from the string (or null if the input is null)
448      * @throws NumberFormatException if the value cannot be converted
449      */
450     public static Number createNumber(final String str) throws NumberFormatException {
451         if (str == null) {
452             return null;
453         }
454         if (StringUtils.isBlank(str)) {
455             throw new NumberFormatException("A blank string is not a valid number");
456         }
457         // Need to deal with all possible hex prefixes here
458         final String[] hex_prefixes = {"0x", "0X", "-0x", "-0X", "#", "-#"};
459         int pfxLen = 0;
460         for(final String pfx : hex_prefixes) {
461             if (str.startsWith(pfx)) {
462                 pfxLen += pfx.length();
463                 break;
464             }
465         }
466         if (pfxLen > 0) { // we have a hex number
467             char firstSigDigit = 0; // strip leading zeroes
468             for(int i = pfxLen; i < str.length(); i++) {
469                 firstSigDigit = str.charAt(i);
470                 if (firstSigDigit == '0') { // count leading zeroes
471                     pfxLen++;
472                 } else {
473                     break;
474                 }
475             }
476             final int hexDigits = str.length() - pfxLen;
477             if (hexDigits > 16 || (hexDigits == 16 && firstSigDigit > '7')) { // too many for Long
478                 return createBigInteger(str);
479             }
480             if (hexDigits > 8 || (hexDigits == 8 && firstSigDigit > '7')) { // too many for an int
481                 return createLong(str);
482             }
483             return createInteger(str);
484         }
485         final char lastChar = str.charAt(str.length() - 1);
486         String mant;
487         String dec;
488         String exp;
489         final int decPos = str.indexOf('.');
490         final int expPos = str.indexOf('e') + str.indexOf('E') + 1; // assumes both not present
491         // if both e and E are present, this is caught by the checks on expPos (which prevent IOOBE)
492         // and the parsing which will detect if e or E appear in a number due to using the wrong offset
493 
494         if (decPos > -1) { // there is a decimal point
495             if (expPos > -1) { // there is an exponent
496                 if (expPos < decPos || expPos > str.length()) { // prevents double exponent causing IOOBE
497                     throw new NumberFormatException(str + " is not a valid number.");
498                 }
499                 dec = str.substring(decPos + 1, expPos);
500             } else {
501                 dec = str.substring(decPos + 1);
502             }
503             mant = getMantissa(str, decPos);
504         } else {
505             if (expPos > -1) {
506                 if (expPos > str.length()) { // prevents double exponent causing IOOBE
507                     throw new NumberFormatException(str + " is not a valid number.");
508                 }
509                 mant = getMantissa(str, expPos);
510             } else {
511                 mant = getMantissa(str);
512             }
513             dec = null;
514         }
515         if (!Character.isDigit(lastChar) && lastChar != '.') {
516             if (expPos > -1 && expPos < str.length() - 1) {
517                 exp = str.substring(expPos + 1, str.length() - 1);
518             } else {
519                 exp = null;
520             }
521             //Requesting a specific type..
522             final String numeric = str.substring(0, str.length() - 1);
523             final boolean allZeros = isAllZeros(mant) && isAllZeros(exp);
524             switch (lastChar) {
525                 case 'l' :
526                 case 'L' :
527                     if (dec == null
528                         && exp == null
529                         && (numeric.charAt(0) == '-' && isDigits(numeric.substring(1)) || isDigits(numeric))) {
530                         try {
531                             return createLong(numeric);
532                         } catch (final NumberFormatException nfe) { // NOPMD
533                             // Too big for a long
534                         }
535                         return createBigInteger(numeric);
536 
537                     }
538                     throw new NumberFormatException(str + " is not a valid number.");
539                 case 'f' :
540                 case 'F' :
541                     try {
542                         final Float f = NumberUtils.createFloat(str);
543                         if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) {
544                             //If it's too big for a float or the float value = 0 and the string
545                             //has non-zeros in it, then float does not have the precision we want
546                             return f;
547                         }
548 
549                     } catch (final NumberFormatException nfe) { // NOPMD
550                         // ignore the bad number
551                     }
552                     //$FALL-THROUGH$
553                 case 'd' :
554                 case 'D' :
555                     try {
556                         final Double d = NumberUtils.createDouble(str);
557                         if (!(d.isInfinite() || (d.floatValue() == 0.0D && !allZeros))) {
558                             return d;
559                         }
560                     } catch (final NumberFormatException nfe) { // NOPMD
561                         // ignore the bad number
562                     }
563                     try {
564                         return createBigDecimal(numeric);
565                     } catch (final NumberFormatException e) { // NOPMD
566                         // ignore the bad number
567                     }
568                     //$FALL-THROUGH$
569                 default :
570                     throw new NumberFormatException(str + " is not a valid number.");
571 
572             }
573         }
574         //User doesn't have a preference on the return type, so let's start
575         //small and go from there...
576         if (expPos > -1 && expPos < str.length() - 1) {
577             exp = str.substring(expPos + 1, str.length());
578         } else {
579             exp = null;
580         }
581         if (dec == null && exp == null) { // no decimal point and no exponent
582             //Must be an Integer, Long, Biginteger
583             try {
584                 return createInteger(str);
585             } catch (final NumberFormatException nfe) { // NOPMD
586                 // ignore the bad number
587             }
588             try {
589                 return createLong(str);
590             } catch (final NumberFormatException nfe) { // NOPMD
591                 // ignore the bad number
592             }
593             return createBigInteger(str);
594         }
595 
596         //Must be a Float, Double, BigDecimal
597         final boolean allZeros = isAllZeros(mant) && isAllZeros(exp);
598         try {
599             final Float f = createFloat(str);
600             final Double d = createDouble(str);
601             if (!f.isInfinite()
602                     && !(f.floatValue() == 0.0F && !allZeros)
603                     && f.toString().equals(d.toString())) {
604                 return f;
605             }
606             if (!d.isInfinite() && !(d.doubleValue() == 0.0D && !allZeros)) {
607                 final BigDecimal b = createBigDecimal(str);
608                 if (b.compareTo(BigDecimal.valueOf(d)) == 0) {
609                     return d;
610                 }
611                 return b;
612             }
613         } catch (final NumberFormatException nfe) { // NOPMD
614             // ignore the bad number
615         }
616         return createBigDecimal(str);
617     }
618 
619     /**
620      * <p>Utility method for {@link #createNumber(java.lang.String)}.</p>
621      *
622      * <p>Returns mantissa of the given number.</p>
623      * 
624      * @param str the string representation of the number
625      * @return mantissa of the given number
626      */
627     private static String getMantissa(final String str) {
628         return getMantissa(str, str.length());
629     }
630 
631     /**
632      * <p>Utility method for {@link #createNumber(java.lang.String)}.</p>
633      *
634      * <p>Returns mantissa of the given number.</p>
635      * 
636      * @param str the string representation of the number
637      * @param stopPos the position of the exponent or decimal point
638      * @return mantissa of the given number
639      */
640     private static String getMantissa(final String str, final int stopPos) {
641         final char firstChar = str.charAt(0);
642         final boolean hasSign = (firstChar == '-' || firstChar == '+');
643 
644         return hasSign ? str.substring(1, stopPos) : str.substring(0, stopPos);
645     }
646 
647     /**
648      * <p>Utility method for {@link #createNumber(java.lang.String)}.</p>
649      *
650      * <p>Returns <code>true</code> if s is <code>null</code>.</p>
651      * 
652      * @param str  the String to check
653      * @return if it is all zeros or <code>null</code>
654      */
655     private static boolean isAllZeros(final String str) {
656         if (str == null) {
657             return true;
658         }
659         for (int i = str.length() - 1; i >= 0; i--) {
660             if (str.charAt(i) != '0') {
661                 return false;
662             }
663         }
664         return str.length() > 0;
665     }
666 
667     //-----------------------------------------------------------------------
668     /**
669      * <p>Convert a <code>String</code> to a <code>Float</code>.</p>
670      *
671      * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
672      * 
673      * @param str  a <code>String</code> to convert, may be null
674      * @return converted <code>Float</code> (or null if the input is null)
675      * @throws NumberFormatException if the value cannot be converted
676      */
677     public static Float createFloat(final String str) {
678         if (str == null) {
679             return null;
680         }
681         return Float.valueOf(str);
682     }
683 
684     /**
685      * <p>Convert a <code>String</code> to a <code>Double</code>.</p>
686      * 
687      * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
688      *
689      * @param str  a <code>String</code> to convert, may be null
690      * @return converted <code>Double</code> (or null if the input is null)
691      * @throws NumberFormatException if the value cannot be converted
692      */
693     public static Double createDouble(final String str) {
694         if (str == null) {
695             return null;
696         }
697         return Double.valueOf(str);
698     }
699 
700     /**
701      * <p>Convert a <code>String</code> to a <code>Integer</code>, handling
702      * hex (0xhhhh) and octal (0dddd) notations.
703      * N.B. a leading zero means octal; spaces are not trimmed.</p>
704      *
705      * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
706      * 
707      * @param str  a <code>String</code> to convert, may be null
708      * @return converted <code>Integer</code> (or null if the input is null)
709      * @throws NumberFormatException if the value cannot be converted
710      */
711     public static Integer createInteger(final String str) {
712         if (str == null) {
713             return null;
714         }
715         // decode() handles 0xAABD and 0777 (hex and octal) as well.
716         return Integer.decode(str);
717     }
718 
719     /**
720      * <p>Convert a <code>String</code> to a <code>Long</code>; 
721      * since 3.1 it handles hex (0Xhhhh) and octal (0ddd) notations.
722      * N.B. a leading zero means octal; spaces are not trimmed.</p>
723      * 
724      * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
725      *
726      * @param str  a <code>String</code> to convert, may be null
727      * @return converted <code>Long</code> (or null if the input is null)
728      * @throws NumberFormatException if the value cannot be converted
729      */
730     public static Long createLong(final String str) {
731         if (str == null) {
732             return null;
733         }
734         return Long.decode(str);
735     }
736 
737     /**
738      * <p>Convert a <code>String</code> to a <code>BigInteger</code>;
739      * since 3.2 it handles hex (0x or #) and octal (0) notations.</p>
740      *
741      * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
742      * 
743      * @param str  a <code>String</code> to convert, may be null
744      * @return converted <code>BigInteger</code> (or null if the input is null)
745      * @throws NumberFormatException if the value cannot be converted
746      */
747     public static BigInteger createBigInteger(final String str) {
748         if (str == null) {
749             return null;
750         }
751         int pos = 0; // offset within string
752         int radix = 10;
753         boolean negate = false; // need to negate later?
754         if (str.startsWith("-")) {
755             negate = true;
756             pos = 1;
757         }
758         if (str.startsWith("0x", pos) || str.startsWith("0X", pos)) { // hex
759             radix = 16;
760             pos += 2;
761         } else if (str.startsWith("#", pos)) { // alternative hex (allowed by Long/Integer)
762             radix = 16;
763             pos ++;
764         } else if (str.startsWith("0", pos) && str.length() > pos + 1) { // octal; so long as there are additional digits
765             radix = 8;
766             pos ++;
767         } // default is to treat as decimal
768 
769         final BigInteger value = new BigInteger(str.substring(pos), radix);
770         return negate ? value.negate() : value;
771     }
772 
773     /**
774      * <p>Convert a <code>String</code> to a <code>BigDecimal</code>.</p>
775      * 
776      * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
777      *
778      * @param str  a <code>String</code> to convert, may be null
779      * @return converted <code>BigDecimal</code> (or null if the input is null)
780      * @throws NumberFormatException if the value cannot be converted
781      */
782     public static BigDecimal createBigDecimal(final String str) {
783         if (str == null) {
784             return null;
785         }
786         // handle JDK1.3.1 bug where "" throws IndexOutOfBoundsException
787         if (StringUtils.isBlank(str)) {
788             throw new NumberFormatException("A blank string is not a valid number");
789         }
790         if (str.trim().startsWith("--")) {
791             // this is protection for poorness in java.lang.BigDecimal.
792             // it accepts this as a legal value, but it does not appear 
793             // to be in specification of class. OS X Java parses it to 
794             // a wrong value.
795             throw new NumberFormatException(str + " is not a valid number.");
796         }
797         return new BigDecimal(str);
798     }
799 
800     // Min in array
801     //--------------------------------------------------------------------
802     /**
803      * <p>Returns the minimum value in an array.</p>
804      * 
805      * @param array  an array, must not be null or empty
806      * @return the minimum value in the array
807      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
808      * @throws IllegalArgumentException if <code>array</code> is empty
809      * @since 3.4 Changed signature from min(long[]) to min(long...)
810      */
811     public static long min(final long... array) {
812         // Validates input
813         validateArray(array);
814     
815         // Finds and returns min
816         long min = array[0];
817         for (int i = 1; i < array.length; i++) {
818             if (array[i] < min) {
819                 min = array[i];
820             }
821         }
822     
823         return min;
824     }
825 
826     /**
827      * <p>Returns the minimum value in an array.</p>
828      * 
829      * @param array  an array, must not be null or empty
830      * @return the minimum value in the array
831      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
832      * @throws IllegalArgumentException if <code>array</code> is empty
833      * @since 3.4 Changed signature from min(int[]) to min(int...)
834      */
835     public static int min(final int... array) {
836         // Validates input
837         validateArray(array);
838     
839         // Finds and returns min
840         int min = array[0];
841         for (int j = 1; j < array.length; j++) {
842             if (array[j] < min) {
843                 min = array[j];
844             }
845         }
846     
847         return min;
848     }
849 
850     /**
851      * <p>Returns the minimum value in an array.</p>
852      * 
853      * @param array  an array, must not be null or empty
854      * @return the minimum value in the array
855      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
856      * @throws IllegalArgumentException if <code>array</code> is empty
857      * @since 3.4 Changed signature from min(short[]) to min(short...)
858      */
859     public static short min(final short... array) {
860         // Validates input
861         validateArray(array);
862     
863         // Finds and returns min
864         short min = array[0];
865         for (int i = 1; i < array.length; i++) {
866             if (array[i] < min) {
867                 min = array[i];
868             }
869         }
870     
871         return min;
872     }
873 
874     /**
875      * <p>Returns the minimum value in an array.</p>
876      * 
877      * @param array  an array, must not be null or empty
878      * @return the minimum value in the array
879      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
880      * @throws IllegalArgumentException if <code>array</code> is empty
881      * @since 3.4 Changed signature from min(byte[]) to min(byte...)
882      */
883     public static byte min(final byte... array) {
884         // Validates input
885         validateArray(array);
886     
887         // Finds and returns min
888         byte min = array[0];
889         for (int i = 1; i < array.length; i++) {
890             if (array[i] < min) {
891                 min = array[i];
892             }
893         }
894     
895         return min;
896     }
897 
898      /**
899      * <p>Returns the minimum value in an array.</p>
900      * 
901      * @param array  an array, must not be null or empty
902      * @return the minimum value in the array
903      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
904      * @throws IllegalArgumentException if <code>array</code> is empty
905      * @see IEEE754rUtils#min(double[]) IEEE754rUtils for a version of this method that handles NaN differently
906      * @since 3.4 Changed signature from min(double[]) to min(double...)
907      */
908     public static double min(final double... array) {
909         // Validates input
910         validateArray(array);
911     
912         // Finds and returns min
913         double min = array[0];
914         for (int i = 1; i < array.length; i++) {
915             if (Double.isNaN(array[i])) {
916                 return Double.NaN;
917             }
918             if (array[i] < min) {
919                 min = array[i];
920             }
921         }
922     
923         return min;
924     }
925 
926     /**
927      * <p>Returns the minimum value in an array.</p>
928      * 
929      * @param array  an array, must not be null or empty
930      * @return the minimum value in the array
931      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
932      * @throws IllegalArgumentException if <code>array</code> is empty
933      * @see IEEE754rUtils#min(float[]) IEEE754rUtils for a version of this method that handles NaN differently
934      * @since 3.4 Changed signature from min(float[]) to min(float...)
935      */
936     public static float min(final float... array) {
937         // Validates input
938         validateArray(array);
939     
940         // Finds and returns min
941         float min = array[0];
942         for (int i = 1; i < array.length; i++) {
943             if (Float.isNaN(array[i])) {
944                 return Float.NaN;
945             }
946             if (array[i] < min) {
947                 min = array[i];
948             }
949         }
950     
951         return min;
952     }
953 
954     // Max in array
955     //--------------------------------------------------------------------
956     /**
957      * <p>Returns the maximum value in an array.</p>
958      * 
959      * @param array  an array, must not be null or empty
960      * @return the maximum value in the array
961      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
962      * @throws IllegalArgumentException if <code>array</code> is empty
963      * @since 3.4 Changed signature from max(long[]) to max(long...)
964      */
965     public static long max(final long... array) {
966         // Validates input
967         validateArray(array);
968 
969         // Finds and returns max
970         long max = array[0];
971         for (int j = 1; j < array.length; j++) {
972             if (array[j] > max) {
973                 max = array[j];
974             }
975         }
976 
977         return max;
978     }
979 
980     /**
981      * <p>Returns the maximum value in an array.</p>
982      * 
983      * @param array  an array, must not be null or empty
984      * @return the maximum value in the array
985      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
986      * @throws IllegalArgumentException if <code>array</code> is empty
987      * @since 3.4 Changed signature from max(int[]) to max(int...)
988      */
989     public static int max(final int... array) {
990         // Validates input
991         validateArray(array);
992     
993         // Finds and returns max
994         int max = array[0];
995         for (int j = 1; j < array.length; j++) {
996             if (array[j] > max) {
997                 max = array[j];
998             }
999         }
1000     
1001         return max;
1002     }
1003 
1004     /**
1005      * <p>Returns the maximum value in an array.</p>
1006      * 
1007      * @param array  an array, must not be null or empty
1008      * @return the maximum value in the array
1009      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
1010      * @throws IllegalArgumentException if <code>array</code> is empty
1011      * @since 3.4 Changed signature from max(short[]) to max(short...)
1012      */
1013     public static short max(final short... array) {
1014         // Validates input
1015         validateArray(array);
1016     
1017         // Finds and returns max
1018         short max = array[0];
1019         for (int i = 1; i < array.length; i++) {
1020             if (array[i] > max) {
1021                 max = array[i];
1022             }
1023         }
1024     
1025         return max;
1026     }
1027 
1028     /**
1029      * <p>Returns the maximum value in an array.</p>
1030      * 
1031      * @param array  an array, must not be null or empty
1032      * @return the maximum value in the array
1033      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
1034      * @throws IllegalArgumentException if <code>array</code> is empty
1035      * @since 3.4 Changed signature from max(byte[]) to max(byte...)
1036      */
1037     public static byte max(final byte... array) {
1038         // Validates input
1039         validateArray(array);
1040     
1041         // Finds and returns max
1042         byte max = array[0];
1043         for (int i = 1; i < array.length; i++) {
1044             if (array[i] > max) {
1045                 max = array[i];
1046             }
1047         }
1048     
1049         return max;
1050     }
1051 
1052     /**
1053      * <p>Returns the maximum value in an array.</p>
1054      * 
1055      * @param array  an array, must not be null or empty
1056      * @return the maximum value in the array
1057      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
1058      * @throws IllegalArgumentException if <code>array</code> is empty
1059      * @see IEEE754rUtils#max(double[]) IEEE754rUtils for a version of this method that handles NaN differently
1060      * @since 3.4 Changed signature from max(double[]) to max(double...)
1061      */
1062     public static double max(final double... array) {
1063         // Validates input
1064         validateArray(array);
1065 
1066         // Finds and returns max
1067         double max = array[0];
1068         for (int j = 1; j < array.length; j++) {
1069             if (Double.isNaN(array[j])) {
1070                 return Double.NaN;
1071             }
1072             if (array[j] > max) {
1073                 max = array[j];
1074             }
1075         }
1076     
1077         return max;
1078     }
1079 
1080     /**
1081      * <p>Returns the maximum value in an array.</p>
1082      * 
1083      * @param array  an array, must not be null or empty
1084      * @return the maximum value in the array
1085      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
1086      * @throws IllegalArgumentException if <code>array</code> is empty
1087      * @see IEEE754rUtils#max(float[]) IEEE754rUtils for a version of this method that handles NaN differently
1088      * @since 3.4 Changed signature from max(float[]) to max(float...)
1089      */
1090     public static float max(final float... array) {
1091         // Validates input
1092         validateArray(array);
1093 
1094         // Finds and returns max
1095         float max = array[0];
1096         for (int j = 1; j < array.length; j++) {
1097             if (Float.isNaN(array[j])) {
1098                 return Float.NaN;
1099             }
1100             if (array[j] > max) {
1101                 max = array[j];
1102             }
1103         }
1104 
1105         return max;
1106     }
1107 
1108     /**
1109      * Checks if the specified array is neither null nor empty.
1110      *
1111      * @param array  the array to check
1112      * @throws IllegalArgumentException if {@code array} is either {@code null} or empty
1113      */
1114     private static void validateArray(final Object array) {
1115         if (array == null) {
1116             throw new IllegalArgumentException("The Array must not be null");
1117         }        
1118         Validate.isTrue(Array.getLength(array) != 0, "Array cannot be empty.");        
1119     }
1120      
1121     // 3 param min
1122     //-----------------------------------------------------------------------
1123     /**
1124      * <p>Gets the minimum of three <code>long</code> values.</p>
1125      * 
1126      * @param a  value 1
1127      * @param b  value 2
1128      * @param c  value 3
1129      * @return  the smallest of the values
1130      */
1131     public static long min(long a, final long b, final long c) {
1132         if (b < a) {
1133             a = b;
1134         }
1135         if (c < a) {
1136             a = c;
1137         }
1138         return a;
1139     }
1140 
1141     /**
1142      * <p>Gets the minimum of three <code>int</code> values.</p>
1143      * 
1144      * @param a  value 1
1145      * @param b  value 2
1146      * @param c  value 3
1147      * @return  the smallest of the values
1148      */
1149     public static int min(int a, final int b, final int c) {
1150         if (b < a) {
1151             a = b;
1152         }
1153         if (c < a) {
1154             a = c;
1155         }
1156         return a;
1157     }
1158 
1159     /**
1160      * <p>Gets the minimum of three <code>short</code> values.</p>
1161      * 
1162      * @param a  value 1
1163      * @param b  value 2
1164      * @param c  value 3
1165      * @return  the smallest of the values
1166      */
1167     public static short min(short a, final short b, final short c) {
1168         if (b < a) {
1169             a = b;
1170         }
1171         if (c < a) {
1172             a = c;
1173         }
1174         return a;
1175     }
1176 
1177     /**
1178      * <p>Gets the minimum of three <code>byte</code> values.</p>
1179      * 
1180      * @param a  value 1
1181      * @param b  value 2
1182      * @param c  value 3
1183      * @return  the smallest of the values
1184      */
1185     public static byte min(byte a, final byte b, final byte c) {
1186         if (b < a) {
1187             a = b;
1188         }
1189         if (c < a) {
1190             a = c;
1191         }
1192         return a;
1193     }
1194 
1195     /**
1196      * <p>Gets the minimum of three <code>double</code> values.</p>
1197      * 
1198      * <p>If any value is <code>NaN</code>, <code>NaN</code> is
1199      * returned. Infinity is handled.</p>
1200      * 
1201      * @param a  value 1
1202      * @param b  value 2
1203      * @param c  value 3
1204      * @return  the smallest of the values
1205      * @see IEEE754rUtils#min(double, double, double) for a version of this method that handles NaN differently
1206      */
1207     public static double min(final double a, final double b, final double c) {
1208         return Math.min(Math.min(a, b), c);
1209     }
1210 
1211     /**
1212      * <p>Gets the minimum of three <code>float</code> values.</p>
1213      * 
1214      * <p>If any value is <code>NaN</code>, <code>NaN</code> is
1215      * returned. Infinity is handled.</p>
1216      *
1217      * @param a  value 1
1218      * @param b  value 2
1219      * @param c  value 3
1220      * @return  the smallest of the values
1221      * @see IEEE754rUtils#min(float, float, float) for a version of this method that handles NaN differently
1222      */
1223     public static float min(final float a, final float b, final float c) {
1224         return Math.min(Math.min(a, b), c);
1225     }
1226 
1227     // 3 param max
1228     //-----------------------------------------------------------------------
1229     /**
1230      * <p>Gets the maximum of three <code>long</code> values.</p>
1231      * 
1232      * @param a  value 1
1233      * @param b  value 2
1234      * @param c  value 3
1235      * @return  the largest of the values
1236      */
1237     public static long max(long a, final long b, final long c) {
1238         if (b > a) {
1239             a = b;
1240         }
1241         if (c > a) {
1242             a = c;
1243         }
1244         return a;
1245     }
1246 
1247     /**
1248      * <p>Gets the maximum of three <code>int</code> values.</p>
1249      * 
1250      * @param a  value 1
1251      * @param b  value 2
1252      * @param c  value 3
1253      * @return  the largest of the values
1254      */
1255     public static int max(int a, final int b, final int c) {
1256         if (b > a) {
1257             a = b;
1258         }
1259         if (c > a) {
1260             a = c;
1261         }
1262         return a;
1263     }
1264 
1265     /**
1266      * <p>Gets the maximum of three <code>short</code> values.</p>
1267      * 
1268      * @param a  value 1
1269      * @param b  value 2
1270      * @param c  value 3
1271      * @return  the largest of the values
1272      */
1273     public static short max(short a, final short b, final short c) {
1274         if (b > a) {
1275             a = b;
1276         }
1277         if (c > a) {
1278             a = c;
1279         }
1280         return a;
1281     }
1282 
1283     /**
1284      * <p>Gets the maximum of three <code>byte</code> values.</p>
1285      * 
1286      * @param a  value 1
1287      * @param b  value 2
1288      * @param c  value 3
1289      * @return  the largest of the values
1290      */
1291     public static byte max(byte a, final byte b, final byte c) {
1292         if (b > a) {
1293             a = b;
1294         }
1295         if (c > a) {
1296             a = c;
1297         }
1298         return a;
1299     }
1300 
1301     /**
1302      * <p>Gets the maximum of three <code>double</code> values.</p>
1303      * 
1304      * <p>If any value is <code>NaN</code>, <code>NaN</code> is
1305      * returned. Infinity is handled.</p>
1306      *
1307      * @param a  value 1
1308      * @param b  value 2
1309      * @param c  value 3
1310      * @return  the largest of the values
1311      * @see IEEE754rUtils#max(double, double, double) for a version of this method that handles NaN differently
1312      */
1313     public static double max(final double a, final double b, final double c) {
1314         return Math.max(Math.max(a, b), c);
1315     }
1316 
1317     /**
1318      * <p>Gets the maximum of three <code>float</code> values.</p>
1319      * 
1320      * <p>If any value is <code>NaN</code>, <code>NaN</code> is
1321      * returned. Infinity is handled.</p>
1322      *
1323      * @param a  value 1
1324      * @param b  value 2
1325      * @param c  value 3
1326      * @return  the largest of the values
1327      * @see IEEE754rUtils#max(float, float, float) for a version of this method that handles NaN differently
1328      */
1329     public static float max(final float a, final float b, final float c) {
1330         return Math.max(Math.max(a, b), c);
1331     }
1332 
1333     //-----------------------------------------------------------------------
1334     /**
1335      * <p>Checks whether the <code>String</code> contains only
1336      * digit characters.</p>
1337      *
1338      * <p><code>Null</code> and empty String will return
1339      * <code>false</code>.</p>
1340      *
1341      * @param str  the <code>String</code> to check
1342      * @return <code>true</code> if str contains only Unicode numeric
1343      */
1344     public static boolean isDigits(final String str) {
1345         return StringUtils.isNumeric(str);
1346     }
1347 
1348     /**
1349      * <p>Checks whether the String a valid Java number.</p>
1350      *
1351      * <p>Valid numbers include hexadecimal marked with the <code>0x</code> or
1352      * <code>0X</code> qualifier, octal numbers, scientific notation and numbers 
1353      * marked with a type qualifier (e.g. 123L).</p>
1354      * 
1355      * <p>Non-hexadecimal strings beginning with a leading zero are
1356      * treated as octal values. Thus the string <code>09</code> will return
1357      * <code>false</code>, since <code>9</code> is not a valid octal value.
1358      * However, numbers beginning with {@code 0.} are treated as decimal.</p>
1359      *
1360      * <p><code>null</code> and empty/blank {@code String} will return
1361      * <code>false</code>.</p>
1362      *
1363      * @param str  the <code>String</code> to check
1364      * @return <code>true</code> if the string is a correctly formatted number
1365      * @since 3.3 the code supports hex {@code 0Xhhh} and octal {@code 0ddd} validation
1366      */
1367     public static boolean isNumber(final String str) {
1368         if (StringUtils.isEmpty(str)) {
1369             return false;
1370         }
1371         final char[] chars = str.toCharArray();
1372         int sz = chars.length;
1373         boolean hasExp = false;
1374         boolean hasDecPoint = false;
1375         boolean allowSigns = false;
1376         boolean foundDigit = false;
1377         // deal with any possible sign up front
1378         final int start = (chars[0] == '-') ? 1 : 0;
1379         if (sz > start + 1 && chars[start] == '0') { // leading 0
1380             if (
1381                  (chars[start + 1] == 'x') || 
1382                  (chars[start + 1] == 'X') 
1383             ) { // leading 0x/0X
1384                 int i = start + 2;
1385                 if (i == sz) {
1386                     return false; // str == "0x"
1387                 }
1388                 // checking hex (it can't be anything else)
1389                 for (; i < chars.length; i++) {
1390                     if ((chars[i] < '0' || chars[i] > '9')
1391                         && (chars[i] < 'a' || chars[i] > 'f')
1392                         && (chars[i] < 'A' || chars[i] > 'F')) {
1393                         return false;
1394                     }
1395                 }
1396                 return true;
1397            } else if (Character.isDigit(chars[start + 1])) {
1398                // leading 0, but not hex, must be octal
1399                int i = start + 1;
1400                for (; i < chars.length; i++) {
1401                    if (chars[i] < '0' || chars[i] > '7') {
1402                        return false;
1403                    }
1404                }
1405                return true;               
1406            }
1407         }
1408         sz--; // don't want to loop to the last char, check it afterwords
1409               // for type qualifiers
1410         int i = start;
1411         // loop to the next to last char or to the last char if we need another digit to
1412         // make a valid number (e.g. chars[0..5] = "1234E")
1413         while (i < sz || (i < sz + 1 && allowSigns && !foundDigit)) {
1414             if (chars[i] >= '0' && chars[i] <= '9') {
1415                 foundDigit = true;
1416                 allowSigns = false;
1417 
1418             } else if (chars[i] == '.') {
1419                 if (hasDecPoint || hasExp) {
1420                     // two decimal points or dec in exponent   
1421                     return false;
1422                 }
1423                 hasDecPoint = true;
1424             } else if (chars[i] == 'e' || chars[i] == 'E') {
1425                 // we've already taken care of hex.
1426                 if (hasExp) {
1427                     // two E's
1428                     return false;
1429                 }
1430                 if (!foundDigit) {
1431                     return false;
1432                 }
1433                 hasExp = true;
1434                 allowSigns = true;
1435             } else if (chars[i] == '+' || chars[i] == '-') {
1436                 if (!allowSigns) {
1437                     return false;
1438                 }
1439                 allowSigns = false;
1440                 foundDigit = false; // we need a digit after the E
1441             } else {
1442                 return false;
1443             }
1444             i++;
1445         }
1446         if (i < chars.length) {
1447             if (chars[i] >= '0' && chars[i] <= '9') {
1448                 // no type qualifier, OK
1449                 return true;
1450             }
1451             if (chars[i] == 'e' || chars[i] == 'E') {
1452                 // can't have an E at the last byte
1453                 return false;
1454             }
1455             if (chars[i] == '.') {
1456                 if (hasDecPoint || hasExp) {
1457                     // two decimal points or dec in exponent
1458                     return false;
1459                 }
1460                 // single trailing decimal point after non-exponent is ok
1461                 return foundDigit;
1462             }
1463             if (!allowSigns
1464                 && (chars[i] == 'd'
1465                     || chars[i] == 'D'
1466                     || chars[i] == 'f'
1467                     || chars[i] == 'F')) {
1468                 return foundDigit;
1469             }
1470             if (chars[i] == 'l'
1471                 || chars[i] == 'L') {
1472                 // not allowing L with an exponent or decimal point
1473                 return foundDigit && !hasExp && !hasDecPoint;
1474             }
1475             // last character is illegal
1476             return false;
1477         }
1478         // allowSigns is true iff the val ends in 'E'
1479         // found digit it to make sure weird stuff like '.' and '1E-' doesn't pass
1480         return !allowSigns && foundDigit;
1481     }
1482     
1483     /**
1484      * <p>Checks whether the given String is a parsable number.</p>
1485      *
1486      * <p>Parsable numbers include those Strings understood by {@link Integer#parseInt(String)},
1487      * {@link Long#parseLong(String)}, {@link Float#parseFloat(String)} or
1488      * {@link Double#parseDouble(String)}. This method can be used instead of catching {@link java.text.ParseException}
1489      * when calling one of those methods.</p>
1490      *
1491      * <p>Hexadecimal and scientific notations are <strong>not</strong> considered parsable.
1492      * See {@link #isNumber(String)} on those cases.</p>
1493      *
1494      * <p>{@code Null} and empty String will return <code>false</code>.</p>
1495      *
1496      * @param str the String to check.
1497      * @return {@code true} if the string is a parsable number.
1498      * @since 3.4
1499      */
1500     public static boolean isParsable(final String str) {
1501         if (StringUtils.isEmpty(str)) {
1502             return false;
1503         }
1504         if (str.charAt(str.length() - 1) == '.') {
1505             return false;
1506         }
1507         if (str.charAt(0) == '-') {
1508             if (str.length() == 1) {
1509                 return false;
1510             }
1511             return withDecimalsParsing(str, 1);
1512         } else {
1513             return withDecimalsParsing(str, 0);
1514         }
1515     }
1516 
1517     private static boolean withDecimalsParsing(final String str, final int beginIdx) {
1518         int decimalPoints = 0;
1519         for (int i = beginIdx; i < str.length(); i++) {
1520             final boolean isDecimalPoint = str.charAt(i) == '.';
1521             if (isDecimalPoint) {
1522                 decimalPoints++;
1523             }
1524             if (decimalPoints > 1) {
1525                 return false;
1526             }
1527             if (!isDecimalPoint && !Character.isDigit(str.charAt(i))) {
1528                 return false;
1529             }
1530         }
1531         return true;
1532     }
1533 
1534     /**
1535      * <p>Compares two {@code int} values numerically. This is the same functionality as provided in Java 7.</p>
1536      *
1537      * @param x the first {@code int} to compare
1538      * @param y the second {@code int} to compare
1539      * @return the value {@code 0} if {@code x == y};
1540      *         a value less than {@code 0} if {@code x < y}; and
1541      *         a value greater than {@code 0} if {@code x > y}
1542      * @since 3.4
1543      */
1544     public static int compare(int x, int y) {
1545         if (x == y) {
1546             return 0;
1547         }
1548         return x < y ? -1 : 1;
1549     }
1550 
1551     /**
1552      * <p>Compares to {@code long} values numerically. This is the same functionality as provided in Java 7.</p>
1553      *
1554      * @param x the first {@code long} to compare
1555      * @param y the second {@code long} to compare
1556      * @return the value {@code 0} if {@code x == y};
1557      *         a value less than {@code 0} if {@code x < y}; and
1558      *         a value greater than {@code 0} if {@code x > y}
1559      * @since 3.4
1560      */
1561     public static int compare(long x, long y) {
1562         if (x == y) {
1563             return 0;
1564         }
1565         return x < y ? -1 : 1;
1566     }
1567 
1568     /**
1569      * <p>Compares to {@code short} values numerically. This is the same functionality as provided in Java 7.</p>
1570      *
1571      * @param x the first {@code short} to compare
1572      * @param y the second {@code short} to compare
1573      * @return the value {@code 0} if {@code x == y};
1574      *         a value less than {@code 0} if {@code x < y}; and
1575      *         a value greater than {@code 0} if {@code x > y}
1576      * @since 3.4
1577      */
1578     public static int compare(short x, short y) {
1579         if (x == y) {
1580             return 0;
1581         }
1582         return x < y ? -1 : 1;
1583     }
1584 
1585     /**
1586      * <p>Compares two {@code byte} values numerically. This is the same functionality as provided in Java 7.</p>
1587      *
1588      * @param x the first {@code byte} to compare
1589      * @param y the second {@code byte} to compare
1590      * @return the value {@code 0} if {@code x == y};
1591      *         a value less than {@code 0} if {@code x < y}; and
1592      *         a value greater than {@code 0} if {@code x > y}
1593      * @since 3.4
1594      */
1595     public static int compare(byte x, byte y) {
1596         return x - y;
1597     }
1598 }