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