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)) == 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        if (array == null) {
1117            throw new IllegalArgumentException("The Array must not be null");
1118        }        
1119        Validate.isTrue(Array.getLength(array) != 0, "Array cannot be empty.");        
1120    }
1121     
1122    // 3 param min
1123    //-----------------------------------------------------------------------
1124    /**
1125     * <p>Gets the minimum of three <code>long</code> values.</p>
1126     * 
1127     * @param a  value 1
1128     * @param b  value 2
1129     * @param c  value 3
1130     * @return  the smallest of the values
1131     */
1132    public static long min(long a, final long b, final long c) {
1133        if (b < a) {
1134            a = b;
1135        }
1136        if (c < a) {
1137            a = c;
1138        }
1139        return a;
1140    }
1141
1142    /**
1143     * <p>Gets the minimum of three <code>int</code> values.</p>
1144     * 
1145     * @param a  value 1
1146     * @param b  value 2
1147     * @param c  value 3
1148     * @return  the smallest of the values
1149     */
1150    public static int min(int a, final int b, final int c) {
1151        if (b < a) {
1152            a = b;
1153        }
1154        if (c < a) {
1155            a = c;
1156        }
1157        return a;
1158    }
1159
1160    /**
1161     * <p>Gets the minimum of three <code>short</code> values.</p>
1162     * 
1163     * @param a  value 1
1164     * @param b  value 2
1165     * @param c  value 3
1166     * @return  the smallest of the values
1167     */
1168    public static short min(short a, final short b, final short c) {
1169        if (b < a) {
1170            a = b;
1171        }
1172        if (c < a) {
1173            a = c;
1174        }
1175        return a;
1176    }
1177
1178    /**
1179     * <p>Gets the minimum of three <code>byte</code> values.</p>
1180     * 
1181     * @param a  value 1
1182     * @param b  value 2
1183     * @param c  value 3
1184     * @return  the smallest of the values
1185     */
1186    public static byte min(byte a, final byte b, final byte c) {
1187        if (b < a) {
1188            a = b;
1189        }
1190        if (c < a) {
1191            a = c;
1192        }
1193        return a;
1194    }
1195
1196    /**
1197     * <p>Gets the minimum of three <code>double</code> values.</p>
1198     * 
1199     * <p>If any value is <code>NaN</code>, <code>NaN</code> is
1200     * returned. Infinity is handled.</p>
1201     * 
1202     * @param a  value 1
1203     * @param b  value 2
1204     * @param c  value 3
1205     * @return  the smallest of the values
1206     * @see IEEE754rUtils#min(double, double, double) for a version of this method that handles NaN differently
1207     */
1208    public static double min(final double a, final double b, final double c) {
1209        return Math.min(Math.min(a, b), c);
1210    }
1211
1212    /**
1213     * <p>Gets the minimum of three <code>float</code> values.</p>
1214     * 
1215     * <p>If any value is <code>NaN</code>, <code>NaN</code> is
1216     * returned. Infinity is handled.</p>
1217     *
1218     * @param a  value 1
1219     * @param b  value 2
1220     * @param c  value 3
1221     * @return  the smallest of the values
1222     * @see IEEE754rUtils#min(float, float, float) for a version of this method that handles NaN differently
1223     */
1224    public static float min(final float a, final float b, final float c) {
1225        return Math.min(Math.min(a, b), c);
1226    }
1227
1228    // 3 param max
1229    //-----------------------------------------------------------------------
1230    /**
1231     * <p>Gets the maximum of three <code>long</code> values.</p>
1232     * 
1233     * @param a  value 1
1234     * @param b  value 2
1235     * @param c  value 3
1236     * @return  the largest of the values
1237     */
1238    public static long max(long a, final long b, final long c) {
1239        if (b > a) {
1240            a = b;
1241        }
1242        if (c > a) {
1243            a = c;
1244        }
1245        return a;
1246    }
1247
1248    /**
1249     * <p>Gets the maximum of three <code>int</code> values.</p>
1250     * 
1251     * @param a  value 1
1252     * @param b  value 2
1253     * @param c  value 3
1254     * @return  the largest of the values
1255     */
1256    public static int max(int a, final int b, final int c) {
1257        if (b > a) {
1258            a = b;
1259        }
1260        if (c > a) {
1261            a = c;
1262        }
1263        return a;
1264    }
1265
1266    /**
1267     * <p>Gets the maximum of three <code>short</code> values.</p>
1268     * 
1269     * @param a  value 1
1270     * @param b  value 2
1271     * @param c  value 3
1272     * @return  the largest of the values
1273     */
1274    public static short max(short a, final short b, final short c) {
1275        if (b > a) {
1276            a = b;
1277        }
1278        if (c > a) {
1279            a = c;
1280        }
1281        return a;
1282    }
1283
1284    /**
1285     * <p>Gets the maximum of three <code>byte</code> values.</p>
1286     * 
1287     * @param a  value 1
1288     * @param b  value 2
1289     * @param c  value 3
1290     * @return  the largest of the values
1291     */
1292    public static byte max(byte a, final byte b, final byte c) {
1293        if (b > a) {
1294            a = b;
1295        }
1296        if (c > a) {
1297            a = c;
1298        }
1299        return a;
1300    }
1301
1302    /**
1303     * <p>Gets the maximum of three <code>double</code> values.</p>
1304     * 
1305     * <p>If any value is <code>NaN</code>, <code>NaN</code> is
1306     * returned. Infinity is handled.</p>
1307     *
1308     * @param a  value 1
1309     * @param b  value 2
1310     * @param c  value 3
1311     * @return  the largest of the values
1312     * @see IEEE754rUtils#max(double, double, double) for a version of this method that handles NaN differently
1313     */
1314    public static double max(final double a, final double b, final double c) {
1315        return Math.max(Math.max(a, b), c);
1316    }
1317
1318    /**
1319     * <p>Gets the maximum of three <code>float</code> values.</p>
1320     * 
1321     * <p>If any value is <code>NaN</code>, <code>NaN</code> is
1322     * returned. Infinity is handled.</p>
1323     *
1324     * @param a  value 1
1325     * @param b  value 2
1326     * @param c  value 3
1327     * @return  the largest of the values
1328     * @see IEEE754rUtils#max(float, float, float) for a version of this method that handles NaN differently
1329     */
1330    public static float max(final float a, final float b, final float c) {
1331        return Math.max(Math.max(a, b), c);
1332    }
1333
1334    //-----------------------------------------------------------------------
1335    /**
1336     * <p>Checks whether the <code>String</code> contains only
1337     * digit characters.</p>
1338     *
1339     * <p><code>Null</code> and empty String will return
1340     * <code>false</code>.</p>
1341     *
1342     * @param str  the <code>String</code> to check
1343     * @return <code>true</code> if str contains only Unicode numeric
1344     */
1345    public static boolean isDigits(final String str) {
1346        return StringUtils.isNumeric(str);
1347    }
1348
1349    /**
1350     * <p>Checks whether the String a valid Java number.</p>
1351     *
1352     * <p>Valid numbers include hexadecimal marked with the <code>0x</code> or
1353     * <code>0X</code> qualifier, octal numbers, scientific notation and
1354     * numbers marked with a type qualifier (e.g. 123L).</p>
1355     *
1356     * <p>Non-hexadecimal strings beginning with a leading zero are
1357     * treated as octal values. Thus the string <code>09</code> will return
1358     * <code>false</code>, since <code>9</code> is not a valid octal value.
1359     * However, numbers beginning with {@code 0.} are treated as decimal.</p>
1360     *
1361     * <p><code>null</code> and empty/blank {@code String} will return
1362     * <code>false</code>.</p>
1363     *
1364     * <p>Note, {@link #createNumber(String)} should return a number for every
1365     * input resuling in <code>true</code>.</p>
1366     *
1367     * @param str  the <code>String</code> to check
1368     * @return <code>true</code> if the string is a correctly formatted number
1369     * @since 3.3 the code supports hex {@code 0Xhhh} an
1370     *        octal {@code 0ddd} validation
1371     * @deprecated This feature will be removed in Lang 4.0,
1372     *             use {@link NumberUtils#isCreatable(String)} instead
1373     */
1374    @Deprecated
1375    public static boolean isNumber(final String str) {
1376        return isCreatable(str);
1377    }
1378
1379    /**
1380     * <p>Checks whether the String a valid Java number.</p>
1381     *
1382     * <p>Valid numbers include hexadecimal marked with the <code>0x</code> or
1383     * <code>0X</code> qualifier, octal numbers, scientific notation and
1384     * numbers marked with a type qualifier (e.g. 123L).</p>
1385     *
1386     * <p>Non-hexadecimal strings beginning with a leading zero are
1387     * treated as octal values. Thus the string <code>09</code> will return
1388     * <code>false</code>, since <code>9</code> is not a valid octal value.
1389     * However, numbers beginning with {@code 0.} are treated as decimal.</p>
1390     *
1391     * <p><code>null</code> and empty/blank {@code String} will return
1392     * <code>false</code>.</p>
1393     *
1394     * <p>Note, {@link #createNumber(String)} should return a number for every
1395     * input resuling in <code>true</code>.</p>
1396     *
1397     * @param str  the <code>String</code> to check
1398     * @return <code>true</code> if the string is a correctly formatted number
1399     * @since 3.5 the code supports the "+" suffix on numbers except for integers in Java 1.6
1400     */
1401    public static boolean isCreatable(final String str) {
1402        if (StringUtils.isEmpty(str)) {
1403            return false;
1404        }
1405        final char[] chars = str.toCharArray();
1406        int sz = chars.length;
1407        boolean hasExp = false;
1408        boolean hasDecPoint = false;
1409        boolean allowSigns = false;
1410        boolean foundDigit = false;
1411        // deal with any possible sign up front
1412        final int start = chars[0] == '-' || chars[0] == '+' ? 1 : 0;
1413        final boolean hasLeadingPlusSign = start == 1 && chars[0] == '+';
1414        if (sz > start + 1 && chars[start] == '0') { // leading 0
1415            if (chars[start + 1] == 'x' || chars[start + 1] == 'X') { // leading 0x/0X
1416                int i = start + 2;
1417                if (i == sz) {
1418                    return false; // str == "0x"
1419                }
1420                // checking hex (it can't be anything else)
1421                for (; i < chars.length; i++) {
1422                    if ((chars[i] < '0' || chars[i] > '9')
1423                        && (chars[i] < 'a' || chars[i] > 'f')
1424                        && (chars[i] < 'A' || chars[i] > 'F')) {
1425                        return false;
1426                    }
1427                }
1428                return true;
1429           } else if (Character.isDigit(chars[start + 1])) {
1430               // leading 0, but not hex, must be octal
1431               int i = start + 1;
1432               for (; i < chars.length; i++) {
1433                   if (chars[i] < '0' || chars[i] > '7') {
1434                       return false;
1435                   }
1436               }
1437               return true;               
1438           }
1439        }
1440        sz--; // don't want to loop to the last char, check it afterwords
1441              // for type qualifiers
1442        int i = start;
1443        // loop to the next to last char or to the last char if we need another digit to
1444        // make a valid number (e.g. chars[0..5] = "1234E")
1445        while (i < sz || i < sz + 1 && allowSigns && !foundDigit) {
1446            if (chars[i] >= '0' && chars[i] <= '9') {
1447                foundDigit = true;
1448                allowSigns = false;
1449
1450            } else if (chars[i] == '.') {
1451                if (hasDecPoint || hasExp) {
1452                    // two decimal points or dec in exponent   
1453                    return false;
1454                }
1455                hasDecPoint = true;
1456            } else if (chars[i] == 'e' || chars[i] == 'E') {
1457                // we've already taken care of hex.
1458                if (hasExp) {
1459                    // two E's
1460                    return false;
1461                }
1462                if (!foundDigit) {
1463                    return false;
1464                }
1465                hasExp = true;
1466                allowSigns = true;
1467            } else if (chars[i] == '+' || chars[i] == '-') {
1468                if (!allowSigns) {
1469                    return false;
1470                }
1471                allowSigns = false;
1472                foundDigit = false; // we need a digit after the E
1473            } else {
1474                return false;
1475            }
1476            i++;
1477        }
1478        if (i < chars.length) {
1479            if (chars[i] >= '0' && chars[i] <= '9') {
1480                if (SystemUtils.IS_JAVA_1_6 && hasLeadingPlusSign && !hasDecPoint) {
1481                    return false;
1482                }
1483                // no type qualifier, OK
1484                return true;
1485            }
1486            if (chars[i] == 'e' || chars[i] == 'E') {
1487                // can't have an E at the last byte
1488                return false;
1489            }
1490            if (chars[i] == '.') {
1491                if (hasDecPoint || hasExp) {
1492                    // two decimal points or dec in exponent
1493                    return false;
1494                }
1495                // single trailing decimal point after non-exponent is ok
1496                return foundDigit;
1497            }
1498            if (!allowSigns
1499                && (chars[i] == 'd'
1500                    || chars[i] == 'D'
1501                    || chars[i] == 'f'
1502                    || chars[i] == 'F')) {
1503                return foundDigit;
1504            }
1505            if (chars[i] == 'l'
1506                || chars[i] == 'L') {
1507                // not allowing L with an exponent or decimal point
1508                return foundDigit && !hasExp && !hasDecPoint;
1509            }
1510            // last character is illegal
1511            return false;
1512        }
1513        // allowSigns is true iff the val ends in 'E'
1514        // found digit it to make sure weird stuff like '.' and '1E-' doesn't pass
1515        return !allowSigns && foundDigit;
1516    }
1517    
1518    /**
1519     * <p>Checks whether the given String is a parsable number.</p>
1520     *
1521     * <p>Parsable numbers include those Strings understood by {@link Integer#parseInt(String)},
1522     * {@link Long#parseLong(String)}, {@link Float#parseFloat(String)} or
1523     * {@link Double#parseDouble(String)}. This method can be used instead of catching {@link java.text.ParseException}
1524     * when calling one of those methods.</p>
1525     *
1526     * <p>Hexadecimal and scientific notations are <strong>not</strong> considered parsable.
1527     * See {@link #isCreatable(String)} on those cases.</p>
1528     *
1529     * <p>{@code Null} and empty String will return <code>false</code>.</p>
1530     *
1531     * @param str the String to check.
1532     * @return {@code true} if the string is a parsable number.
1533     * @since 3.4
1534     */
1535    public static boolean isParsable(final String str) {
1536        if (StringUtils.isEmpty(str)) {
1537            return false;
1538        }
1539        if (str.charAt(str.length() - 1) == '.') {
1540            return false;
1541        }
1542        if (str.charAt(0) == '-') {
1543            if (str.length() == 1) {
1544                return false;
1545            }
1546            return withDecimalsParsing(str, 1);
1547        } else {
1548            return withDecimalsParsing(str, 0);
1549        }
1550    }
1551
1552    private static boolean withDecimalsParsing(final String str, final int beginIdx) {
1553        int decimalPoints = 0;
1554        for (int i = beginIdx; i < str.length(); i++) {
1555            final boolean isDecimalPoint = str.charAt(i) == '.';
1556            if (isDecimalPoint) {
1557                decimalPoints++;
1558            }
1559            if (decimalPoints > 1) {
1560                return false;
1561            }
1562            if (!isDecimalPoint && !Character.isDigit(str.charAt(i))) {
1563                return false;
1564            }
1565        }
1566        return true;
1567    }
1568
1569    /**
1570     * <p>Compares two {@code int} values numerically. This is the same functionality as provided in Java 7.</p>
1571     *
1572     * @param x the first {@code int} to compare
1573     * @param y the second {@code int} to compare
1574     * @return the value {@code 0} if {@code x == y};
1575     *         a value less than {@code 0} if {@code x < y}; and
1576     *         a value greater than {@code 0} if {@code x > y}
1577     * @since 3.4
1578     */
1579    public static int compare(int x, int y) {
1580        if (x == y) {
1581            return 0;
1582        }
1583        return x < y ? -1 : 1;
1584    }
1585
1586    /**
1587     * <p>Compares to {@code long} values numerically. This is the same functionality as provided in Java 7.</p>
1588     *
1589     * @param x the first {@code long} to compare
1590     * @param y the second {@code long} to compare
1591     * @return the value {@code 0} if {@code x == y};
1592     *         a value less than {@code 0} if {@code x < y}; and
1593     *         a value greater than {@code 0} if {@code x > y}
1594     * @since 3.4
1595     */
1596    public static int compare(long x, long y) {
1597        if (x == y) {
1598            return 0;
1599        }
1600        return x < y ? -1 : 1;
1601    }
1602
1603    /**
1604     * <p>Compares to {@code short} values numerically. This is the same functionality as provided in Java 7.</p>
1605     *
1606     * @param x the first {@code short} to compare
1607     * @param y the second {@code short} to compare
1608     * @return the value {@code 0} if {@code x == y};
1609     *         a value less than {@code 0} if {@code x < y}; and
1610     *         a value greater than {@code 0} if {@code x > y}
1611     * @since 3.4
1612     */
1613    public static int compare(short x, short y) {
1614        if (x == y) {
1615            return 0;
1616        }
1617        return x < y ? -1 : 1;
1618    }
1619
1620    /**
1621     * <p>Compares two {@code byte} values numerically. This is the same functionality as provided in Java 7.</p>
1622     *
1623     * @param x the first {@code byte} to compare
1624     * @param y the second {@code byte} to compare
1625     * @return the value {@code 0} if {@code x == y};
1626     *         a value less than {@code 0} if {@code x < y}; and
1627     *         a value greater than {@code 0} if {@code x > y}
1628     * @since 3.4
1629     */
1630    public static int compare(byte x, byte y) {
1631        return x - y;
1632    }
1633}