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