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