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         int numDecimals = 0; // Check required precision (LANG-693)
495         if (decPos > -1) { // there is a decimal point
496 
497             if (expPos > -1) { // there is an exponent
498                 if (expPos < decPos || expPos > str.length()) { // prevents double exponent causing IOOBE
499                     throw new NumberFormatException(str + " is not a valid number.");
500                 }
501                 dec = str.substring(decPos + 1, expPos);
502             } else {
503                 dec = str.substring(decPos + 1);
504             }
505             mant = getMantissa(str, decPos);
506             numDecimals = dec.length(); // gets number of digits past the decimal to ensure no loss of precision for floating point numbers.
507         } else {
508             if (expPos > -1) {
509                 if (expPos > str.length()) { // prevents double exponent causing IOOBE
510                     throw new NumberFormatException(str + " is not a valid number.");
511                 }
512                 mant = getMantissa(str, expPos);
513             } else {
514                 mant = getMantissa(str);
515             }
516             dec = null;
517         }
518         if (!Character.isDigit(lastChar) && lastChar != '.') {
519             if (expPos > -1 && expPos < str.length() - 1) {
520                 exp = str.substring(expPos + 1, str.length() - 1);
521             } else {
522                 exp = null;
523             }
524             //Requesting a specific type..
525             final String numeric = str.substring(0, str.length() - 1);
526             final boolean allZeros = isAllZeros(mant) && isAllZeros(exp);
527             switch (lastChar) {
528                 case 'l' :
529                 case 'L' :
530                     if (dec == null
531                         && exp == null
532                         && (numeric.charAt(0) == '-' && isDigits(numeric.substring(1)) || isDigits(numeric))) {
533                         try {
534                             return createLong(numeric);
535                         } catch (final NumberFormatException nfe) { // NOPMD
536                             // Too big for a long
537                         }
538                         return createBigInteger(numeric);
539 
540                     }
541                     throw new NumberFormatException(str + " is not a valid number.");
542                 case 'f' :
543                 case 'F' :
544                     try {
545                         final Float f = NumberUtils.createFloat(numeric);
546                         if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) {
547                             //If it's too big for a float or the float value = 0 and the string
548                             //has non-zeros in it, then float does not have the precision we want
549                             return f;
550                         }
551 
552                     } catch (final NumberFormatException nfe) { // NOPMD
553                         // ignore the bad number
554                     }
555                     //$FALL-THROUGH$
556                 case 'd' :
557                 case 'D' :
558                     try {
559                         final Double d = NumberUtils.createDouble(numeric);
560                         if (!(d.isInfinite() || (d.floatValue() == 0.0D && !allZeros))) {
561                             return d;
562                         }
563                     } catch (final NumberFormatException nfe) { // NOPMD
564                         // ignore the bad number
565                     }
566                     try {
567                         return createBigDecimal(numeric);
568                     } catch (final NumberFormatException e) { // NOPMD
569                         // ignore the bad number
570                     }
571                     //$FALL-THROUGH$
572                 default :
573                     throw new NumberFormatException(str + " is not a valid number.");
574 
575             }
576         }
577         //User doesn't have a preference on the return type, so let's start
578         //small and go from there...
579         if (expPos > -1 && expPos < str.length() - 1) {
580             exp = str.substring(expPos + 1, str.length());
581         } else {
582             exp = null;
583         }
584         if (dec == null && exp == null) { // no decimal point and no exponent
585             //Must be an Integer, Long, Biginteger
586             try {
587                 return createInteger(str);
588             } catch (final NumberFormatException nfe) { // NOPMD
589                 // ignore the bad number
590             }
591             try {
592                 return createLong(str);
593             } catch (final NumberFormatException nfe) { // NOPMD
594                 // ignore the bad number
595             }
596             return createBigInteger(str);
597         }
598 
599         //Must be a Float, Double, BigDecimal
600         final boolean allZeros = isAllZeros(mant) && isAllZeros(exp);
601         try {
602             if(numDecimals <= 7){// If number has 7 or fewer digits past the decimal point then make it a float
603                 final Float f = createFloat(str);
604                 if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) {
605                     return f;
606                 }
607             }
608         } catch (final NumberFormatException nfe) { // NOPMD
609             // ignore the bad number
610         }
611         try {
612             if(numDecimals <= 16){// If number has between 8 and 16 digits past the decimal point then make it a double
613                 final Double d = createDouble(str);
614                 if (!(d.isInfinite() || (d.doubleValue() == 0.0D && !allZeros))) {
615                     return d;
616                 }
617             }
618         } catch (final NumberFormatException nfe) { // NOPMD
619             // ignore the bad number
620         }
621 
622         return createBigDecimal(str);
623     }
624 
625     /**
626      * <p>Utility method for {@link #createNumber(java.lang.String)}.</p>
627      *
628      * <p>Returns mantissa of the given number.</p>
629      * 
630      * @param str the string representation of the number
631      * @return mantissa of the given number
632      */
633     private static String getMantissa(final String str) {
634         return getMantissa(str, str.length());
635     }
636 
637     /**
638      * <p>Utility method for {@link #createNumber(java.lang.String)}.</p>
639      *
640      * <p>Returns mantissa of the given number.</p>
641      * 
642      * @param str the string representation of the number
643      * @param stopPos the position of the exponent or decimal point
644      * @return mantissa of the given number
645      */
646     private static String getMantissa(final String str, final int stopPos) {
647         final char firstChar = str.charAt(0);
648         final boolean hasSign = (firstChar == '-' || firstChar == '+');
649 
650         return hasSign ? str.substring(1, stopPos) : str.substring(0, stopPos);
651     }
652 
653     /**
654      * <p>Utility method for {@link #createNumber(java.lang.String)}.</p>
655      *
656      * <p>Returns <code>true</code> if s is <code>null</code>.</p>
657      * 
658      * @param str  the String to check
659      * @return if it is all zeros or <code>null</code>
660      */
661     private static boolean isAllZeros(final String str) {
662         if (str == null) {
663             return true;
664         }
665         for (int i = str.length() - 1; i >= 0; i--) {
666             if (str.charAt(i) != '0') {
667                 return false;
668             }
669         }
670         return str.length() > 0;
671     }
672 
673     //-----------------------------------------------------------------------
674     /**
675      * <p>Convert a <code>String</code> to a <code>Float</code>.</p>
676      *
677      * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
678      * 
679      * @param str  a <code>String</code> to convert, may be null
680      * @return converted <code>Float</code> (or null if the input is null)
681      * @throws NumberFormatException if the value cannot be converted
682      */
683     public static Float createFloat(final String str) {
684         if (str == null) {
685             return null;
686         }
687         return Float.valueOf(str);
688     }
689 
690     /**
691      * <p>Convert a <code>String</code> to a <code>Double</code>.</p>
692      * 
693      * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
694      *
695      * @param str  a <code>String</code> to convert, may be null
696      * @return converted <code>Double</code> (or null if the input is null)
697      * @throws NumberFormatException if the value cannot be converted
698      */
699     public static Double createDouble(final String str) {
700         if (str == null) {
701             return null;
702         }
703         return Double.valueOf(str);
704     }
705 
706     /**
707      * <p>Convert a <code>String</code> to a <code>Integer</code>, handling
708      * hex (0xhhhh) and octal (0dddd) notations.
709      * N.B. a leading zero means octal; spaces are not trimmed.</p>
710      *
711      * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
712      * 
713      * @param str  a <code>String</code> to convert, may be null
714      * @return converted <code>Integer</code> (or null if the input is null)
715      * @throws NumberFormatException if the value cannot be converted
716      */
717     public static Integer createInteger(final String str) {
718         if (str == null) {
719             return null;
720         }
721         // decode() handles 0xAABD and 0777 (hex and octal) as well.
722         return Integer.decode(str);
723     }
724 
725     /**
726      * <p>Convert a <code>String</code> to a <code>Long</code>; 
727      * since 3.1 it handles hex (0Xhhhh) and octal (0ddd) notations.
728      * N.B. a leading zero means octal; spaces are not trimmed.</p>
729      * 
730      * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
731      *
732      * @param str  a <code>String</code> to convert, may be null
733      * @return converted <code>Long</code> (or null if the input is null)
734      * @throws NumberFormatException if the value cannot be converted
735      */
736     public static Long createLong(final String str) {
737         if (str == null) {
738             return null;
739         }
740         return Long.decode(str);
741     }
742 
743     /**
744      * <p>Convert a <code>String</code> to a <code>BigInteger</code>;
745      * since 3.2 it handles hex (0x or #) and octal (0) notations.</p>
746      *
747      * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
748      * 
749      * @param str  a <code>String</code> to convert, may be null
750      * @return converted <code>BigInteger</code> (or null if the input is null)
751      * @throws NumberFormatException if the value cannot be converted
752      */
753     public static BigInteger createBigInteger(final String str) {
754         if (str == null) {
755             return null;
756         }
757         int pos = 0; // offset within string
758         int radix = 10;
759         boolean negate = false; // need to negate later?
760         if (str.startsWith("-")) {
761             negate = true;
762             pos = 1;
763         }
764         if (str.startsWith("0x", pos) || str.startsWith("0X", pos)) { // hex
765             radix = 16;
766             pos += 2;
767         } else if (str.startsWith("#", pos)) { // alternative hex (allowed by Long/Integer)
768             radix = 16;
769             pos ++;
770         } else if (str.startsWith("0", pos) && str.length() > pos + 1) { // octal; so long as there are additional digits
771             radix = 8;
772             pos ++;
773         } // default is to treat as decimal
774 
775         final BigInteger value = new BigInteger(str.substring(pos), radix);
776         return negate ? value.negate() : value;
777     }
778 
779     /**
780      * <p>Convert a <code>String</code> to a <code>BigDecimal</code>.</p>
781      * 
782      * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
783      *
784      * @param str  a <code>String</code> to convert, may be null
785      * @return converted <code>BigDecimal</code> (or null if the input is null)
786      * @throws NumberFormatException if the value cannot be converted
787      */
788     public static BigDecimal createBigDecimal(final String str) {
789         if (str == null) {
790             return null;
791         }
792         // handle JDK1.3.1 bug where "" throws IndexOutOfBoundsException
793         if (StringUtils.isBlank(str)) {
794             throw new NumberFormatException("A blank string is not a valid number");
795         }
796         if (str.trim().startsWith("--")) {
797             // this is protection for poorness in java.lang.BigDecimal.
798             // it accepts this as a legal value, but it does not appear 
799             // to be in specification of class. OS X Java parses it to 
800             // a wrong value.
801             throw new NumberFormatException(str + " is not a valid number.");
802         }
803         return new BigDecimal(str);
804     }
805 
806     // Min in array
807     //--------------------------------------------------------------------
808     /**
809      * <p>Returns the minimum value in an array.</p>
810      * 
811      * @param array  an array, must not be null or empty
812      * @return the minimum value in the array
813      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
814      * @throws IllegalArgumentException if <code>array</code> is empty
815      * @since 3.4 Changed signature from min(long[]) to min(long...)
816      */
817     public static long min(final long... array) {
818         // Validates input
819         validateArray(array);
820     
821         // Finds and returns min
822         long min = array[0];
823         for (int i = 1; i < array.length; i++) {
824             if (array[i] < min) {
825                 min = array[i];
826             }
827         }
828     
829         return min;
830     }
831 
832     /**
833      * <p>Returns the minimum value in an array.</p>
834      * 
835      * @param array  an array, must not be null or empty
836      * @return the minimum value in the array
837      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
838      * @throws IllegalArgumentException if <code>array</code> is empty
839      * @since 3.4 Changed signature from min(int[]) to min(int...)
840      */
841     public static int min(final int... array) {
842         // Validates input
843         validateArray(array);
844     
845         // Finds and returns min
846         int min = array[0];
847         for (int j = 1; j < array.length; j++) {
848             if (array[j] < min) {
849                 min = array[j];
850             }
851         }
852     
853         return min;
854     }
855 
856     /**
857      * <p>Returns the minimum value in an array.</p>
858      * 
859      * @param array  an array, must not be null or empty
860      * @return the minimum value in the array
861      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
862      * @throws IllegalArgumentException if <code>array</code> is empty
863      * @since 3.4 Changed signature from min(short[]) to min(short...)
864      */
865     public static short min(final short... array) {
866         // Validates input
867         validateArray(array);
868     
869         // Finds and returns min
870         short min = array[0];
871         for (int i = 1; i < array.length; i++) {
872             if (array[i] < min) {
873                 min = array[i];
874             }
875         }
876     
877         return min;
878     }
879 
880     /**
881      * <p>Returns the minimum value in an array.</p>
882      * 
883      * @param array  an array, must not be null or empty
884      * @return the minimum value in the array
885      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
886      * @throws IllegalArgumentException if <code>array</code> is empty
887      * @since 3.4 Changed signature from min(byte[]) to min(byte...)
888      */
889     public static byte min(final byte... array) {
890         // Validates input
891         validateArray(array);
892     
893         // Finds and returns min
894         byte min = array[0];
895         for (int i = 1; i < array.length; i++) {
896             if (array[i] < min) {
897                 min = array[i];
898             }
899         }
900     
901         return min;
902     }
903 
904      /**
905      * <p>Returns the minimum value in an array.</p>
906      * 
907      * @param array  an array, must not be null or empty
908      * @return the minimum value in the array
909      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
910      * @throws IllegalArgumentException if <code>array</code> is empty
911      * @see IEEE754rUtils#min(double[]) IEEE754rUtils for a version of this method that handles NaN differently
912      * @since 3.4 Changed signature from min(double[]) to min(double...)
913      */
914     public static double min(final double... array) {
915         // Validates input
916         validateArray(array);
917     
918         // Finds and returns min
919         double min = array[0];
920         for (int i = 1; i < array.length; i++) {
921             if (Double.isNaN(array[i])) {
922                 return Double.NaN;
923             }
924             if (array[i] < min) {
925                 min = array[i];
926             }
927         }
928     
929         return min;
930     }
931 
932     /**
933      * <p>Returns the minimum value in an array.</p>
934      * 
935      * @param array  an array, must not be null or empty
936      * @return the minimum value in the array
937      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
938      * @throws IllegalArgumentException if <code>array</code> is empty
939      * @see IEEE754rUtils#min(float[]) IEEE754rUtils for a version of this method that handles NaN differently
940      * @since 3.4 Changed signature from min(float[]) to min(float...)
941      */
942     public static float min(final float... array) {
943         // Validates input
944         validateArray(array);
945     
946         // Finds and returns min
947         float min = array[0];
948         for (int i = 1; i < array.length; i++) {
949             if (Float.isNaN(array[i])) {
950                 return Float.NaN;
951             }
952             if (array[i] < min) {
953                 min = array[i];
954             }
955         }
956     
957         return min;
958     }
959 
960     // Max in array
961     //--------------------------------------------------------------------
962     /**
963      * <p>Returns the maximum value in an array.</p>
964      * 
965      * @param array  an array, must not be null or empty
966      * @return the maximum value in the array
967      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
968      * @throws IllegalArgumentException if <code>array</code> is empty
969      * @since 3.4 Changed signature from max(long[]) to max(long...)
970      */
971     public static long max(final long... array) {
972         // Validates input
973         validateArray(array);
974 
975         // Finds and returns max
976         long max = array[0];
977         for (int j = 1; j < array.length; j++) {
978             if (array[j] > max) {
979                 max = array[j];
980             }
981         }
982 
983         return max;
984     }
985 
986     /**
987      * <p>Returns the maximum value in an array.</p>
988      * 
989      * @param array  an array, must not be null or empty
990      * @return the maximum value in the array
991      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
992      * @throws IllegalArgumentException if <code>array</code> is empty
993      * @since 3.4 Changed signature from max(int[]) to max(int...)
994      */
995     public static int max(final int... array) {
996         // Validates input
997         validateArray(array);
998     
999         // Finds and returns max
1000         int max = array[0];
1001         for (int j = 1; j < array.length; j++) {
1002             if (array[j] > max) {
1003                 max = array[j];
1004             }
1005         }
1006     
1007         return max;
1008     }
1009 
1010     /**
1011      * <p>Returns the maximum value in an array.</p>
1012      * 
1013      * @param array  an array, must not be null or empty
1014      * @return the maximum value in the array
1015      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
1016      * @throws IllegalArgumentException if <code>array</code> is empty
1017      * @since 3.4 Changed signature from max(short[]) to max(short...)
1018      */
1019     public static short max(final short... array) {
1020         // Validates input
1021         validateArray(array);
1022     
1023         // Finds and returns max
1024         short max = array[0];
1025         for (int i = 1; i < array.length; i++) {
1026             if (array[i] > max) {
1027                 max = array[i];
1028             }
1029         }
1030     
1031         return max;
1032     }
1033 
1034     /**
1035      * <p>Returns the maximum value in an array.</p>
1036      * 
1037      * @param array  an array, must not be null or empty
1038      * @return the maximum value in the array
1039      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
1040      * @throws IllegalArgumentException if <code>array</code> is empty
1041      * @since 3.4 Changed signature from max(byte[]) to max(byte...)
1042      */
1043     public static byte max(final byte... array) {
1044         // Validates input
1045         validateArray(array);
1046     
1047         // Finds and returns max
1048         byte max = array[0];
1049         for (int i = 1; i < array.length; i++) {
1050             if (array[i] > max) {
1051                 max = array[i];
1052             }
1053         }
1054     
1055         return max;
1056     }
1057 
1058     /**
1059      * <p>Returns the maximum value in an array.</p>
1060      * 
1061      * @param array  an array, must not be null or empty
1062      * @return the maximum value in the array
1063      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
1064      * @throws IllegalArgumentException if <code>array</code> is empty
1065      * @see IEEE754rUtils#max(double[]) IEEE754rUtils for a version of this method that handles NaN differently
1066      * @since 3.4 Changed signature from max(double[]) to max(double...)
1067      */
1068     public static double max(final double... array) {
1069         // Validates input
1070         validateArray(array);
1071 
1072         // Finds and returns max
1073         double max = array[0];
1074         for (int j = 1; j < array.length; j++) {
1075             if (Double.isNaN(array[j])) {
1076                 return Double.NaN;
1077             }
1078             if (array[j] > max) {
1079                 max = array[j];
1080             }
1081         }
1082     
1083         return max;
1084     }
1085 
1086     /**
1087      * <p>Returns the maximum value in an array.</p>
1088      * 
1089      * @param array  an array, must not be null or empty
1090      * @return the maximum value in the array
1091      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
1092      * @throws IllegalArgumentException if <code>array</code> is empty
1093      * @see IEEE754rUtils#max(float[]) IEEE754rUtils for a version of this method that handles NaN differently
1094      * @since 3.4 Changed signature from max(float[]) to max(float...)
1095      */
1096     public static float max(final float... array) {
1097         // Validates input
1098         validateArray(array);
1099 
1100         // Finds and returns max
1101         float max = array[0];
1102         for (int j = 1; j < array.length; j++) {
1103             if (Float.isNaN(array[j])) {
1104                 return Float.NaN;
1105             }
1106             if (array[j] > max) {
1107                 max = array[j];
1108             }
1109         }
1110 
1111         return max;
1112     }
1113 
1114     /**
1115      * Checks if the specified array is neither null nor empty.
1116      *
1117      * @param array  the array to check
1118      * @throws IllegalArgumentException if {@code array} is either {@code null} or empty
1119      */
1120     private static void validateArray(final Object array) {
1121         if (array == null) {
1122             throw new IllegalArgumentException("The Array must not be null");
1123         }        
1124         Validate.isTrue(Array.getLength(array) != 0, "Array cannot be empty.");        
1125     }
1126      
1127     // 3 param min
1128     //-----------------------------------------------------------------------
1129     /**
1130      * <p>Gets the minimum of three <code>long</code> values.</p>
1131      * 
1132      * @param a  value 1
1133      * @param b  value 2
1134      * @param c  value 3
1135      * @return  the smallest of the values
1136      */
1137     public static long min(long a, final long b, final long c) {
1138         if (b < a) {
1139             a = b;
1140         }
1141         if (c < a) {
1142             a = c;
1143         }
1144         return a;
1145     }
1146 
1147     /**
1148      * <p>Gets the minimum of three <code>int</code> values.</p>
1149      * 
1150      * @param a  value 1
1151      * @param b  value 2
1152      * @param c  value 3
1153      * @return  the smallest of the values
1154      */
1155     public static int min(int a, final int b, final int c) {
1156         if (b < a) {
1157             a = b;
1158         }
1159         if (c < a) {
1160             a = c;
1161         }
1162         return a;
1163     }
1164 
1165     /**
1166      * <p>Gets the minimum of three <code>short</code> values.</p>
1167      * 
1168      * @param a  value 1
1169      * @param b  value 2
1170      * @param c  value 3
1171      * @return  the smallest of the values
1172      */
1173     public static short min(short a, final short b, final short c) {
1174         if (b < a) {
1175             a = b;
1176         }
1177         if (c < a) {
1178             a = c;
1179         }
1180         return a;
1181     }
1182 
1183     /**
1184      * <p>Gets the minimum of three <code>byte</code> values.</p>
1185      * 
1186      * @param a  value 1
1187      * @param b  value 2
1188      * @param c  value 3
1189      * @return  the smallest of the values
1190      */
1191     public static byte min(byte a, final byte b, final byte c) {
1192         if (b < a) {
1193             a = b;
1194         }
1195         if (c < a) {
1196             a = c;
1197         }
1198         return a;
1199     }
1200 
1201     /**
1202      * <p>Gets the minimum of three <code>double</code> values.</p>
1203      * 
1204      * <p>If any value is <code>NaN</code>, <code>NaN</code> is
1205      * returned. Infinity is handled.</p>
1206      * 
1207      * @param a  value 1
1208      * @param b  value 2
1209      * @param c  value 3
1210      * @return  the smallest of the values
1211      * @see IEEE754rUtils#min(double, double, double) for a version of this method that handles NaN differently
1212      */
1213     public static double min(final double a, final double b, final double c) {
1214         return Math.min(Math.min(a, b), c);
1215     }
1216 
1217     /**
1218      * <p>Gets the minimum of three <code>float</code> values.</p>
1219      * 
1220      * <p>If any value is <code>NaN</code>, <code>NaN</code> is
1221      * returned. Infinity is handled.</p>
1222      *
1223      * @param a  value 1
1224      * @param b  value 2
1225      * @param c  value 3
1226      * @return  the smallest of the values
1227      * @see IEEE754rUtils#min(float, float, float) for a version of this method that handles NaN differently
1228      */
1229     public static float min(final float a, final float b, final float c) {
1230         return Math.min(Math.min(a, b), c);
1231     }
1232 
1233     // 3 param max
1234     //-----------------------------------------------------------------------
1235     /**
1236      * <p>Gets the maximum of three <code>long</code> values.</p>
1237      * 
1238      * @param a  value 1
1239      * @param b  value 2
1240      * @param c  value 3
1241      * @return  the largest of the values
1242      */
1243     public static long max(long a, final long b, final long c) {
1244         if (b > a) {
1245             a = b;
1246         }
1247         if (c > a) {
1248             a = c;
1249         }
1250         return a;
1251     }
1252 
1253     /**
1254      * <p>Gets the maximum of three <code>int</code> values.</p>
1255      * 
1256      * @param a  value 1
1257      * @param b  value 2
1258      * @param c  value 3
1259      * @return  the largest of the values
1260      */
1261     public static int max(int a, final int b, final int c) {
1262         if (b > a) {
1263             a = b;
1264         }
1265         if (c > a) {
1266             a = c;
1267         }
1268         return a;
1269     }
1270 
1271     /**
1272      * <p>Gets the maximum of three <code>short</code> values.</p>
1273      * 
1274      * @param a  value 1
1275      * @param b  value 2
1276      * @param c  value 3
1277      * @return  the largest of the values
1278      */
1279     public static short max(short a, final short b, final short c) {
1280         if (b > a) {
1281             a = b;
1282         }
1283         if (c > a) {
1284             a = c;
1285         }
1286         return a;
1287     }
1288 
1289     /**
1290      * <p>Gets the maximum of three <code>byte</code> values.</p>
1291      * 
1292      * @param a  value 1
1293      * @param b  value 2
1294      * @param c  value 3
1295      * @return  the largest of the values
1296      */
1297     public static byte max(byte a, final byte b, final byte c) {
1298         if (b > a) {
1299             a = b;
1300         }
1301         if (c > a) {
1302             a = c;
1303         }
1304         return a;
1305     }
1306 
1307     /**
1308      * <p>Gets the maximum of three <code>double</code> values.</p>
1309      * 
1310      * <p>If any value is <code>NaN</code>, <code>NaN</code> is
1311      * returned. Infinity is handled.</p>
1312      *
1313      * @param a  value 1
1314      * @param b  value 2
1315      * @param c  value 3
1316      * @return  the largest of the values
1317      * @see IEEE754rUtils#max(double, double, double) for a version of this method that handles NaN differently
1318      */
1319     public static double max(final double a, final double b, final double c) {
1320         return Math.max(Math.max(a, b), c);
1321     }
1322 
1323     /**
1324      * <p>Gets the maximum of three <code>float</code> values.</p>
1325      * 
1326      * <p>If any value is <code>NaN</code>, <code>NaN</code> is
1327      * returned. Infinity is handled.</p>
1328      *
1329      * @param a  value 1
1330      * @param b  value 2
1331      * @param c  value 3
1332      * @return  the largest of the values
1333      * @see IEEE754rUtils#max(float, float, float) for a version of this method that handles NaN differently
1334      */
1335     public static float max(final float a, final float b, final float c) {
1336         return Math.max(Math.max(a, b), c);
1337     }
1338 
1339     //-----------------------------------------------------------------------
1340     /**
1341      * <p>Checks whether the <code>String</code> contains only
1342      * digit characters.</p>
1343      *
1344      * <p><code>Null</code> and empty String will return
1345      * <code>false</code>.</p>
1346      *
1347      * @param str  the <code>String</code> to check
1348      * @return <code>true</code> if str contains only Unicode numeric
1349      */
1350     public static boolean isDigits(final String str) {
1351         if (StringUtils.isEmpty(str)) {
1352             return false;
1353         }
1354         for (int i = 0; i < str.length(); i++) {
1355             if (!Character.isDigit(str.charAt(i))) {
1356                 return false;
1357             }
1358         }
1359         return true;
1360     }
1361 
1362     /**
1363      * <p>Checks whether the String a valid Java number.</p>
1364      *
1365      * <p>Valid numbers include hexadecimal marked with the <code>0x</code> or
1366      * <code>0X</code> qualifier, octal numbers, scientific notation and numbers 
1367      * marked with a type qualifier (e.g. 123L).</p>
1368      * 
1369      * <p>Non-hexadecimal strings beginning with a leading zero are
1370      * treated as octal values. Thus the string <code>09</code> will return
1371      * <code>false</code>, since <code>9</code> is not a valid octal value.
1372      * However, numbers beginning with {@code 0.} are treated as decimal.</p>
1373      *
1374      * <p><code>null</code> and empty/blank {@code String} will return
1375      * <code>false</code>.</p>
1376      *
1377      * @param str  the <code>String</code> to check
1378      * @return <code>true</code> if the string is a correctly formatted number
1379      * @since 3.3 the code supports hex {@code 0Xhhh} and octal {@code 0ddd} validation
1380      */
1381     public static boolean isNumber(final String str) {
1382         if (StringUtils.isEmpty(str)) {
1383             return false;
1384         }
1385         final char[] chars = str.toCharArray();
1386         int sz = chars.length;
1387         boolean hasExp = false;
1388         boolean hasDecPoint = false;
1389         boolean allowSigns = false;
1390         boolean foundDigit = false;
1391         // deal with any possible sign up front
1392         final int start = (chars[0] == '-') ? 1 : 0;
1393         if (sz > start + 1 && chars[start] == '0') { // leading 0
1394             if (
1395                  (chars[start + 1] == 'x') || 
1396                  (chars[start + 1] == 'X') 
1397             ) { // leading 0x/0X
1398                 int i = start + 2;
1399                 if (i == sz) {
1400                     return false; // str == "0x"
1401                 }
1402                 // checking hex (it can't be anything else)
1403                 for (; i < chars.length; i++) {
1404                     if ((chars[i] < '0' || chars[i] > '9')
1405                         && (chars[i] < 'a' || chars[i] > 'f')
1406                         && (chars[i] < 'A' || chars[i] > 'F')) {
1407                         return false;
1408                     }
1409                 }
1410                 return true;
1411            } else if (Character.isDigit(chars[start + 1])) {
1412                // leading 0, but not hex, must be octal
1413                int i = start + 1;
1414                for (; i < chars.length; i++) {
1415                    if (chars[i] < '0' || chars[i] > '7') {
1416                        return false;
1417                    }
1418                }
1419                return true;               
1420            }
1421         }
1422         sz--; // don't want to loop to the last char, check it afterwords
1423               // for type qualifiers
1424         int i = start;
1425         // loop to the next to last char or to the last char if we need another digit to
1426         // make a valid number (e.g. chars[0..5] = "1234E")
1427         while (i < sz || (i < sz + 1 && allowSigns && !foundDigit)) {
1428             if (chars[i] >= '0' && chars[i] <= '9') {
1429                 foundDigit = true;
1430                 allowSigns = false;
1431 
1432             } else if (chars[i] == '.') {
1433                 if (hasDecPoint || hasExp) {
1434                     // two decimal points or dec in exponent   
1435                     return false;
1436                 }
1437                 hasDecPoint = true;
1438             } else if (chars[i] == 'e' || chars[i] == 'E') {
1439                 // we've already taken care of hex.
1440                 if (hasExp) {
1441                     // two E's
1442                     return false;
1443                 }
1444                 if (!foundDigit) {
1445                     return false;
1446                 }
1447                 hasExp = true;
1448                 allowSigns = true;
1449             } else if (chars[i] == '+' || chars[i] == '-') {
1450                 if (!allowSigns) {
1451                     return false;
1452                 }
1453                 allowSigns = false;
1454                 foundDigit = false; // we need a digit after the E
1455             } else {
1456                 return false;
1457             }
1458             i++;
1459         }
1460         if (i < chars.length) {
1461             if (chars[i] >= '0' && chars[i] <= '9') {
1462                 // no type qualifier, OK
1463                 return true;
1464             }
1465             if (chars[i] == 'e' || chars[i] == 'E') {
1466                 // can't have an E at the last byte
1467                 return false;
1468             }
1469             if (chars[i] == '.') {
1470                 if (hasDecPoint || hasExp) {
1471                     // two decimal points or dec in exponent
1472                     return false;
1473                 }
1474                 // single trailing decimal point after non-exponent is ok
1475                 return foundDigit;
1476             }
1477             if (!allowSigns
1478                 && (chars[i] == 'd'
1479                     || chars[i] == 'D'
1480                     || chars[i] == 'f'
1481                     || chars[i] == 'F')) {
1482                 return foundDigit;
1483             }
1484             if (chars[i] == 'l'
1485                 || chars[i] == 'L') {
1486                 // not allowing L with an exponent or decimal point
1487                 return foundDigit && !hasExp && !hasDecPoint;
1488             }
1489             // last character is illegal
1490             return false;
1491         }
1492         // allowSigns is true iff the val ends in 'E'
1493         // found digit it to make sure weird stuff like '.' and '1E-' doesn't pass
1494         return !allowSigns && foundDigit;
1495     }
1496     
1497     /**
1498      * <p>Checks whether the given String is a parsable number.</p>
1499      *
1500      * <p>Parsable numbers include those Strings understood by {@link Integer#parseInt(String)},
1501      * {@link Long#parseLong(String)}, {@link Float#parseFloat(String)} or
1502      * {@link Double#parseDouble(String)}. This method can be used instead of catching {@link java.text.ParseException}
1503      * when calling one of those methods.</p>
1504      *
1505      * <p>Hexadecimal and scientific notations are <strong>not</strong> considered parsable.
1506      * See {@link #isNumber(String)} on those cases.</p>
1507      *
1508      * <p>{@code Null} and empty String will return <code>false</code>.</p>
1509      *
1510      * @param str the String to check.
1511      * @return {@code true} if the string is a parsable number.
1512      * @since 3.4
1513      */
1514     public static boolean isParsable(final String str) {
1515         if( StringUtils.endsWith( str, "." ) ) {
1516             return false;
1517         }
1518         if( StringUtils.startsWith( str, "-" ) ) {
1519             return isDigits( StringUtils.replaceOnce( str.substring(1), ".", StringUtils.EMPTY ) );
1520         } else {
1521             return isDigits( StringUtils.replaceOnce( str, ".", StringUtils.EMPTY ) );
1522         }
1523     }
1524 
1525     /**
1526      * <p>Compares two {@code int} values numerically. This is the same functionality as provided in Java 7.</p>
1527      *
1528      * @param x the first {@code int} to compare
1529      * @param y the second {@code int} to compare
1530      * @return the value {@code 0} if {@code x == y};
1531      *         a value less than {@code 0} if {@code x < y}; and
1532      *         a value greater than {@code 0} if {@code x > y}
1533      * @since 3.4
1534      */
1535     public static int compare(int x, int y) {
1536         if (x == y) {
1537             return 0;
1538         }
1539         if (x < y) {
1540             return -1;
1541         } else {
1542             return 1;
1543         }
1544     }
1545 
1546     /**
1547      * <p>Compares to {@code long} values numerically. This is the same functionality as provided in Java 7.</p>
1548      *
1549      * @param x the first {@code long} to compare
1550      * @param y the second {@code long} to compare
1551      * @return the value {@code 0} if {@code x == y};
1552      *         a value less than {@code 0} if {@code x < y}; and
1553      *         a value greater than {@code 0} if {@code x > y}
1554      * @since 3.4
1555      */
1556     public static int compare(long x, long y) {
1557         if (x == y) {
1558             return 0;
1559         }
1560         if (x < y) {
1561             return -1;
1562         } else {
1563             return 1;
1564         }
1565     }
1566 
1567     /**
1568      * <p>Compares to {@code short} values numerically. This is the same functionality as provided in Java 7.</p>
1569      *
1570      * @param x the first {@code short} to compare
1571      * @param y the second {@code short} to compare
1572      * @return the value {@code 0} if {@code x == y};
1573      *         a value less than {@code 0} if {@code x < y}; and
1574      *         a value greater than {@code 0} if {@code x > y}
1575      * @since 3.4
1576      */
1577     public static int compare(short x, short y) {
1578         if (x == y) {
1579             return 0;
1580         }
1581         if (x < y) {
1582             return -1;
1583         } else {
1584             return 1;
1585         }
1586     }
1587 
1588     /**
1589      * <p>Compares two {@code byte} values numerically. This is the same functionality as provided in Java 7.</p>
1590      *
1591      * @param x the first {@code byte} to compare
1592      * @param y the second {@code byte} to compare
1593      * @return the value {@code 0} if {@code x == y};
1594      *         a value less than {@code 0} if {@code x < y}; and
1595      *         a value greater than {@code 0} if {@code x > y}
1596      * @since 3.4
1597      */
1598     public static int compare(byte x, byte y) {
1599         return x-y;
1600     }
1601 }