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