    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}