    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.lang3.math;
    018
    019import java.lang.reflect.Array;
    020import java.math.BigDecimal;
    021import java.math.BigInteger;
    022
    023import java.math.RoundingMode;
    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</code> instances should NOT be constructed in standard programming.
    076     * Instead, the class should be used as <code>NumberUtils.toInt("6");</code>.</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</code> to an <code>int</code>, returning
    088     * <code>zero</code> if the conversion fails.</p>
    089     *
    090     * <p>If the string is <code>null</code>, <code>zero</code> 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</code> 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</code> to an <code>int</code>, returning a
    109     * default value if the conversion fails.</p>
    110     *
    111     * <p>If the string is <code>null</code>, 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</code> to a <code>long</code>, returning
    137     * <code>zero</code> if the conversion fails.</p>
    138     *
    139     * <p>If the string is <code>null</code>, <code>zero</code> 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</code> 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</code> to a <code>long</code>, returning a
    158     * default value if the conversion fails.</p>
    159     *
    160     * <p>If the string is <code>null</code>, 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</code> to a <code>float</code>, returning
    186     * <code>0.0f</code> if the conversion fails.</p>
    187     *
    188     * <p>If the string <code>str</code> is <code>null</code>,
    189     * <code>0.0f</code> 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</code>
    198     * @return the float represented by the string, or <code>0.0f</code>
    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</code> to a <code>float</code>, returning a
    208     * default value if the conversion fails.</p>
    209     *
    210     * <p>If the string <code>str</code> is <code>null</code>, 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</code>
    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</code> to a <code>double</code>, returning
    238     * <code>0.0d</code> if the conversion fails.</p>
    239     *
    240     * <p>If the string <code>str</code> is <code>null</code>,
    241     * <code>0.0d</code> 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</code>
    250     * @return the double represented by the string, or <code>0.0d</code>
    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</code> to a <code>double</code>, returning a
    260     * default value if the conversion fails.</p>
    261     *
    262     * <p>If the string <code>str</code> is <code>null</code>, 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</code>
    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</code> to a <code>double</code>.</p>
    290     *
    291     * <p>If the <code>BigDecimal</code> <code>value</code> is
    292     * <code>null</code>, 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</code> to convert, may be <code>null</code>.
    300     * @return the double represented by the <code>BigDecimal</code> or
    301     *  <code>0.0d</code> if the <code>BigDecimal</code> is <code>null</code>.
    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</code> to a <code>double</code>.</p>
    310     *
    311     * <p>If the <code>BigDecimal</code> <code>value</code> is
    312     * <code>null</code>, 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</code> to convert, may be <code>null</code>.
    320     * @param defaultValue the default value
    321     * @return the double represented by the <code>BigDecimal</code> or the
    322     *  defaultValue if the <code>BigDecimal</code> is <code>null</code>.
    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</code> to a <code>byte</code>, returning
    332     * <code>zero</code> if the conversion fails.</p>
    333     *
    334     * <p>If the string is <code>null</code>, <code>zero</code> 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</code> 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</code> to a <code>byte</code>, returning a
    353     * default value if the conversion fails.</p>
    354     *
    355     * <p>If the string is <code>null</code>, 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</code> to a <code>short</code>, returning
    381     * <code>zero</code> if the conversion fails.</p>
    382     *
    383     * <p>If the string is <code>null</code>, <code>zero</code> 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</code> 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</code> to an <code>short</code>, returning a
    402     * default value if the conversion fails.</p>
    403     *
    404     * <p>If the string is <code>null</code>, 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</code> to a <code>BigDecimal</code> with a scale of
    430     * two that has been rounded using <code>RoundingMode.HALF_EVEN</code>. If the supplied
    431     * <code>value</code> is null, then <code>BigDecimal.ZERO</code> is returned.
    432     *
    433     * <p>Note, the scale of a <code>BigDecimal</code> is the number of digits to the right of the
    434     * decimal point.</p>
    435     *
    436     * @param value the <code>BigDecimal</code> to convert, may be null.
    437     * @return the scaled, with appropriate rounding, <code>BigDecimal</code>.
    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</code> to a <code>BigDecimal</code> whose scale is the
    446     * specified value with a <code>RoundingMode</code> applied. If the input <code>value</code>
    447     * is <code>null</code>, we simply return <code>BigDecimal.ZERO</code>.
    448     *
    449     * @param value the <code>BigDecimal</code> 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</code>.
    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</code> to a <code>BigDecimal</code> with a scale of
    468     * two that has been rounded using <code>RoundingMode.HALF_EVEN</code>. If the supplied
    469     * <code>value</code> is null, then <code>BigDecimal.ZERO</code> is returned.
    470     *
    471     * <p>Note, the scale of a <code>BigDecimal</code> is the number of digits to the right of the
    472     * decimal point.</p>
    473     *
    474     * @param value the <code>Float</code> to convert, may be null.
    475     * @return the scaled, with appropriate rounding, <code>BigDecimal</code>.
    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</code> to a <code>BigDecimal</code> whose scale is the
    484     * specified value with a <code>RoundingMode</code> applied. If the input <code>value</code>
    485     * is <code>null</code>, we simply return <code>BigDecimal.ZERO</code>.
    486     *
    487     * @param value the <code>Float</code> 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</code>.
    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</code> to a <code>BigDecimal</code> with a scale of
    507     * two that has been rounded using <code>RoundingMode.HALF_EVEN</code>. If the supplied
    508     * <code>value</code> is null, then <code>BigDecimal.ZERO</code> is returned.
    509     *
    510     * <p>Note, the scale of a <code>BigDecimal</code> is the number of digits to the right of the
    511     * decimal point.</p>
    512     *
    513     * @param value the <code>Double</code> to convert, may be null.
    514     * @return the scaled, with appropriate rounding, <code>BigDecimal</code>.
    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</code> to a <code>BigDecimal</code> whose scale is the
    523     * specified value with a <code>RoundingMode</code> applied. If the input <code>value</code>
    524     * is <code>null</code>, we simply return <code>BigDecimal.ZERO</code>.
    525     *
    526     * @param value the <code>Double</code> 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</code>.
    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</code> to a <code>BigDecimal</code> with a scale of
    546     * two that has been rounded using <code>RoundingMode.HALF_EVEN</code>. If the supplied
    547     * <code>value</code> is null, then <code>BigDecimal.ZERO</code> is returned.
    548     *
    549     * <p>Note, the scale of a <code>BigDecimal</code> is the number of digits to the right of the
    550     * decimal point.</p>
    551     *
    552     * @param value the <code>String</code> to convert, may be null.
    553     * @return the scaled, with appropriate rounding, <code>BigDecimal</code>.
    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</code> to a <code>BigDecimal</code> whose scale is the
    562     * specified value with a <code>RoundingMode</code> applied. If the input <code>value</code>
    563     * is <code>null</code>, we simply return <code>BigDecimal.ZERO</code>.
    564     *
    565     * @param value the <code>String</code> 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</code>.
    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'</code>.  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</code> to
    633     * <code>BigInteger</code> and from <code>Float</code> to
    634    * <code>BigDecimal</code>.</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</code> if the string is <code>null</code>.</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</code> if s is <code>null</code>.</p>
    851     *
    852     * @param str  the String to check
    853     * @return if it is all zeros or <code>null</code>
    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</code> to a <code>Float</code>.</p>
    870     *
    871     * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
    872     *
    873     * @param str  a <code>String</code> to convert, may be null
    874     * @return converted <code>Float</code> (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</code> to a <code>Double</code>.</p>
    886     *
    887     * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
    888     *
    889     * @param str  a <code>String</code> to convert, may be null
    890     * @return converted <code>Double</code> (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</code> to a <code>Integer</code>, 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</code> if the string is <code>null</code>.</p>
    906     *
    907     * @param str  a <code>String</code> to convert, may be null
    908     * @return converted <code>Integer</code> (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</code> to a <code>Long</code>;
    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</code> if the string is <code>null</code>.</p>
    925     *
    926     * @param str  a <code>String</code> to convert, may be null
    927     * @return converted <code>Long</code> (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</code> to a <code>BigInteger</code>;
    939     * since 3.2 it handles hex (0x or #) and octal (0) notations.</p>
    940     *
    941     * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
    942     *
    943     * @param str  a <code>String</code> to convert, may be null
    944     * @return converted <code>BigInteger</code> (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</code> to a <code>BigDecimal</code>.</p>
    975     *
    976     * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
    977     *
    978     * @param str  a <code>String</code> to convert, may be null
    979     * @return converted <code>BigDecimal</code> (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        if (str.trim().startsWith("--")) {
    991            // this is protection for poorness in java.lang.BigDecimal.
    992            // it accepts this as a legal value, but it does not appear
    993            // to be in specification of class. OS X Java parses it to
    994            // a wrong value.
    995            throw new NumberFormatException(str + " is not a valid number.");
    996        }
    997        return new BigDecimal(str);
    998    }
    999
    1000    // Min in array
    1001    //--------------------------------------------------------------------
    1002    /**
    1003     * <p>Returns the minimum value in an array.</p>
    1004     *
    1005     * @param array  an array, must not be null or empty
    1006     * @return the minimum value in the array
    1007     * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
    1008     * @throws IllegalArgumentException if <code>array</code> is empty
    1009     * @since 3.4 Changed signature from min(long[]) to min(long...)
    1010     */
    1011    public static long min(final long... array) {
    1012        // Validates input
    1013        validateArray(array);
    1014
    1015        // Finds and returns min
    1016        long min = array[0];
    1017        for (int i = 1; i < array.length; i++) {
    1018            if (array[i] < min) {
    1019                min = array[i];
    1020            }
    1021        }
    1022
    1023        return min;
    1024    }
    1025
    1026    /**
    1027     * <p>Returns the minimum value in an array.</p>
    1028     *
    1029     * @param array  an array, must not be null or empty
    1030     * @return the minimum value in the array
    1031     * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
    1032     * @throws IllegalArgumentException if <code>array</code> is empty
    1033     * @since 3.4 Changed signature from min(int[]) to min(int...)
    1034     */
    1035    public static int min(final int... array) {
    1036        // Validates input
    1037        validateArray(array);
    1038
    1039        // Finds and returns min
    1040        int min = array[0];
    1041        for (int j = 1; j < array.length; j++) {
    1042            if (array[j] < min) {
    1043                min = array[j];
    1044            }
    1045        }
    1046
    1047        return min;
    1048    }
    1049
    1050    /**
    1051     * <p>Returns the minimum value in an array.</p>
    1052     *
    1053     * @param array  an array, must not be null or empty
    1054     * @return the minimum value in the array
    1055     * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
    1056     * @throws IllegalArgumentException if <code>array</code> is empty
    1057     * @since 3.4 Changed signature from min(short[]) to min(short...)
    1058     */
    1059    public static short min(final short... array) {
    1060        // Validates input
    1061        validateArray(array);
    1062
    1063        // Finds and returns min
    1064        short min = array[0];
    1065        for (int i = 1; i < array.length; i++) {
    1066            if (array[i] < min) {
    1067                min = array[i];
    1068            }
    1069        }
    1070
    1071        return min;
    1072    }
    1073
    1074    /**
    1075     * <p>Returns the minimum value in an array.</p>
    1076     *
    1077     * @param array  an array, must not be null or empty
    1078     * @return the minimum value in the array
    1079     * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
    1080     * @throws IllegalArgumentException if <code>array</code> is empty
    1081     * @since 3.4 Changed signature from min(byte[]) to min(byte...)
    1082     */
    1083    public static byte min(final byte... array) {
    1084        // Validates input
    1085        validateArray(array);
    1086
    1087        // Finds and returns min
    1088        byte min = array[0];
    1089        for (int i = 1; i < array.length; i++) {
    1090            if (array[i] < min) {
    1091                min = array[i];
    1092            }
    1093        }
    1094
    1095        return min;
    1096    }
    1097
    1098     /**
    1099     * <p>Returns the minimum value in an array.</p>
    1100     *
    1101     * @param array  an array, must not be null or empty
    1102     * @return the minimum value in the array
    1103     * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
    1104     * @throws IllegalArgumentException if <code>array</code> is empty
    1105     * @see IEEE754rUtils#min(double[]) IEEE754rUtils for a version of this method that handles NaN differently
    1106     * @since 3.4 Changed signature from min(double[]) to min(double...)
    1107     */
    1108    public static double min(final double... array) {
    1109        // Validates input
    1110        validateArray(array);
    1111
    1112        // Finds and returns min
    1113        double min = array[0];
    1114        for (int i = 1; i < array.length; i++) {
    1115            if (Double.isNaN(array[i])) {
    1116                return Double.NaN;
    1117            }
    1118            if (array[i] < min) {
    1119                min = array[i];
    1120            }
    1121        }
    1122
    1123        return min;
    1124    }
    1125
    1126    /**
    1127     * <p>Returns the minimum value in an array.</p>
    1128     *
    1129     * @param array  an array, must not be null or empty
    1130     * @return the minimum value in the array
    1131     * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
    1132     * @throws IllegalArgumentException if <code>array</code> is empty
    1133     * @see IEEE754rUtils#min(float[]) IEEE754rUtils for a version of this method that handles NaN differently
    1134     * @since 3.4 Changed signature from min(float[]) to min(float...)
    1135     */
    1136    public static float min(final float... array) {
    1137        // Validates input
    1138        validateArray(array);
    1139
    1140        // Finds and returns min
    1141        float min = array[0];
    1142        for (int i = 1; i < array.length; i++) {
    1143            if (Float.isNaN(array[i])) {
    1144                return Float.NaN;
    1145            }
    1146            if (array[i] < min) {
    1147                min = array[i];
    1148            }
    1149        }
    1150
    1151        return min;
    1152    }
    1153
    1154    // Max in array
    1155    //--------------------------------------------------------------------
    1156    /**
    1157     * <p>Returns the maximum value in an array.</p>
    1158     *
    1159     * @param array  an array, must not be null or empty
    1160     * @return the maximum value in the array
    1161     * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
    1162     * @throws IllegalArgumentException if <code>array</code> is empty
    1163     * @since 3.4 Changed signature from max(long[]) to max(long...)
    1164     */
    1165    public static long max(final long... array) {
    1166        // Validates input
    1167        validateArray(array);
    1168
    1169        // Finds and returns max
    1170        long max = array[0];
    1171        for (int j = 1; j < array.length; j++) {
    1172            if (array[j] > max) {
    1173                max = array[j];
    1174            }
    1175        }
    1176
    1177        return max;
    1178    }
    1179
    1180    /**
    1181     * <p>Returns the maximum value in an array.</p>
    1182     *
    1183     * @param array  an array, must not be null or empty
    1184     * @return the maximum value in the array
    1185     * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
    1186     * @throws IllegalArgumentException if <code>array</code> is empty
    1187     * @since 3.4 Changed signature from max(int[]) to max(int...)
    1188     */
    1189    public static int max(final int... array) {
    1190        // Validates input
    1191        validateArray(array);
    1192
    1193        // Finds and returns max
    1194        int max = array[0];
    1195        for (int j = 1; j < array.length; j++) {
    1196            if (array[j] > max) {
    1197                max = array[j];
    1198            }
    1199        }
    1200
    1201        return max;
    1202    }
    1203
    1204    /**
    1205     * <p>Returns the maximum value in an array.</p>
    1206     *
    1207     * @param array  an array, must not be null or empty
    1208     * @return the maximum value in the array
    1209     * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
    1210     * @throws IllegalArgumentException if <code>array</code> is empty
    1211     * @since 3.4 Changed signature from max(short[]) to max(short...)
    1212     */
    1213    public static short max(final short... array) {
    1214        // Validates input
    1215        validateArray(array);
    1216
    1217        // Finds and returns max
    1218        short max = array[0];
    1219        for (int i = 1; i < array.length; i++) {
    1220            if (array[i] > max) {
    1221                max = array[i];
    1222            }
    1223        }
    1224
    1225        return max;
    1226    }
    1227
    1228    /**
    1229     * <p>Returns the maximum value in an array.</p>
    1230     *
    1231     * @param array  an array, must not be null or empty
    1232     * @return the maximum value in the array
    1233     * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
    1234     * @throws IllegalArgumentException if <code>array</code> is empty
    1235     * @since 3.4 Changed signature from max(byte[]) to max(byte...)
    1236     */
    1237    public static byte max(final byte... array) {
    1238        // Validates input
    1239        validateArray(array);
    1240
    1241        // Finds and returns max
    1242        byte max = array[0];
    1243        for (int i = 1; i < array.length; i++) {
    1244            if (array[i] > max) {
    1245                max = array[i];
    1246            }
    1247        }
    1248
    1249        return max;
    1250    }
    1251
    1252    /**
    1253     * <p>Returns the maximum value in an array.</p>
    1254     *
    1255     * @param array  an array, must not be null or empty
    1256     * @return the maximum value in the array
    1257     * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
    1258     * @throws IllegalArgumentException if <code>array</code> is empty
    1259     * @see IEEE754rUtils#max(double[]) IEEE754rUtils for a version of this method that handles NaN differently
    1260     * @since 3.4 Changed signature from max(double[]) to max(double...)
    1261     */
    1262    public static double max(final double... array) {
    1263        // Validates input
    1264        validateArray(array);
    1265
    1266        // Finds and returns max
    1267        double max = array[0];
    1268        for (int j = 1; j < array.length; j++) {
    1269            if (Double.isNaN(array[j])) {
    1270                return Double.NaN;
    1271            }
    1272            if (array[j] > max) {
    1273                max = array[j];
    1274            }
    1275        }
    1276
    1277        return max;
    1278    }
    1279
    1280    /**
    1281     * <p>Returns the maximum value in an array.</p>
    1282     *
    1283     * @param array  an array, must not be null or empty
    1284     * @return the maximum value in the array
    1285     * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
    1286     * @throws IllegalArgumentException if <code>array</code> is empty
    1287     * @see IEEE754rUtils#max(float[]) IEEE754rUtils for a version of this method that handles NaN differently
    1288     * @since 3.4 Changed signature from max(float[]) to max(float...)
    1289     */
    1290    public static float max(final float... array) {
    1291        // Validates input
    1292        validateArray(array);
    1293
    1294        // Finds and returns max
    1295        float max = array[0];
    1296        for (int j = 1; j < array.length; j++) {
    1297            if (Float.isNaN(array[j])) {
    1298                return Float.NaN;
    1299            }
    1300            if (array[j] > max) {
    1301                max = array[j];
    1302            }
    1303        }
    1304
    1305        return max;
    1306    }
    1307
    1308    /**
    1309     * Checks if the specified array is neither null nor empty.
    1310     *
    1311     * @param array  the array to check
    1312     * @throws IllegalArgumentException if {@code array} is either {@code null} or empty
    1313     */
    1314    private static void validateArray(final Object array) {
    1315        Validate.isTrue(array != null, "The Array must not be null");
    1316        Validate.isTrue(Array.getLength(array) != 0, "Array cannot be empty.");
    1317    }
    1318
    1319    // 3 param min
    1320    //-----------------------------------------------------------------------
    1321    /**
    1322     * <p>Gets the minimum of three <code>long</code> values.</p>
    1323     *
    1324     * @param a  value 1
    1325     * @param b  value 2
    1326     * @param c  value 3
    1327     * @return  the smallest of the values
    1328     */
    1329    public static long min(long a, final long b, final long c) {
    1330        if (b < a) {
    1331            a = b;
    1332        }
    1333        if (c < a) {
    1334            a = c;
    1335        }
    1336        return a;
    1337    }
    1338
    1339    /**
    1340     * <p>Gets the minimum of three <code>int</code> values.</p>
    1341     *
    1342     * @param a  value 1
    1343     * @param b  value 2
    1344     * @param c  value 3
    1345     * @return  the smallest of the values
    1346     */
    1347    public static int min(int a, final int b, final int c) {
    1348        if (b < a) {
    1349            a = b;
    1350        }
    1351        if (c < a) {
    1352            a = c;
    1353        }
    1354        return a;
    1355    }
    1356
    1357    /**
    1358     * <p>Gets the minimum of three <code>short</code> values.</p>
    1359     *
    1360     * @param a  value 1
    1361     * @param b  value 2
    1362     * @param c  value 3
    1363     * @return  the smallest of the values
    1364     */
    1365    public static short min(short a, final short b, final short c) {
    1366        if (b < a) {
    1367            a = b;
    1368        }
    1369        if (c < a) {
    1370            a = c;
    1371        }
    1372        return a;
    1373    }
    1374
    1375    /**
    1376     * <p>Gets the minimum of three <code>byte</code> values.</p>
    1377     *
    1378     * @param a  value 1
    1379     * @param b  value 2
    1380     * @param c  value 3
    1381     * @return  the smallest of the values
    1382     */
    1383    public static byte min(byte a, final byte b, final byte c) {
    1384        if (b < a) {
    1385            a = b;
    1386        }
    1387        if (c < a) {
    1388            a = c;
    1389        }
    1390        return a;
    1391    }
    1392
    1393    /**
    1394     * <p>Gets the minimum of three <code>double</code> values.</p>
    1395     *
    1396     * <p>If any value is <code>NaN</code>, <code>NaN</code> is
    1397     * returned. Infinity is handled.</p>
    1398     *
    1399     * @param a  value 1
    1400     * @param b  value 2
    1401     * @param c  value 3
    1402     * @return  the smallest of the values
    1403     * @see IEEE754rUtils#min(double, double, double) for a version of this method that handles NaN differently
    1404     */
    1405    public static double min(final double a, final double b, final double c) {
    1406        return Math.min(Math.min(a, b), c);
    1407    }
    1408
    1409    /**
    1410     * <p>Gets the minimum of three <code>float</code> values.</p>
    1411     *
    1412     * <p>If any value is <code>NaN</code>, <code>NaN</code> is
    1413     * returned. Infinity is handled.</p>
    1414     *
    1415     * @param a  value 1
    1416     * @param b  value 2
    1417     * @param c  value 3
    1418     * @return  the smallest of the values
    1419     * @see IEEE754rUtils#min(float, float, float) for a version of this method that handles NaN differently
    1420     */
    1421    public static float min(final float a, final float b, final float c) {
    1422        return Math.min(Math.min(a, b), c);
    1423    }
    1424
    1425    // 3 param max
    1426    //-----------------------------------------------------------------------
    1427    /**
    1428     * <p>Gets the maximum of three <code>long</code> values.</p>
    1429     *
    1430     * @param a  value 1
    1431     * @param b  value 2
    1432     * @param c  value 3
    1433     * @return  the largest of the values
    1434     */
    1435    public static long max(long a, final long b, final long c) {
    1436        if (b > a) {
    1437            a = b;
    1438        }
    1439        if (c > a) {
    1440            a = c;
    1441        }
    1442        return a;
    1443    }
    1444
    1445    /**
    1446     * <p>Gets the maximum of three <code>int</code> values.</p>
    1447     *
    1448     * @param a  value 1
    1449     * @param b  value 2
    1450     * @param c  value 3
    1451     * @return  the largest of the values
    1452     */
    1453    public static int max(int a, final int b, final int c) {
    1454        if (b > a) {
    1455            a = b;
    1456        }
    1457        if (c > a) {
    1458            a = c;
    1459        }
    1460        return a;
    1461    }
    1462
    1463    /**
    1464     * <p>Gets the maximum of three <code>short</code> values.</p>
    1465     *
    1466     * @param a  value 1
    1467     * @param b  value 2
    1468     * @param c  value 3
    1469     * @return  the largest of the values
    1470     */
    1471    public static short max(short a, final short b, final short c) {
    1472        if (b > a) {
    1473            a = b;
    1474        }
    1475        if (c > a) {
    1476            a = c;
    1477        }
    1478        return a;
    1479    }
    1480
    1481    /**
    1482     * <p>Gets the maximum of three <code>byte</code> values.</p>
    1483     *
    1484     * @param a  value 1
    1485     * @param b  value 2
    1486     * @param c  value 3
    1487     * @return  the largest of the values
    1488     */
    1489    public static byte max(byte a, final byte b, final byte c) {
    1490        if (b > a) {
    1491            a = b;
    1492        }
    1493        if (c > a) {
    1494            a = c;
    1495        }
    1496        return a;
    1497    }
    1498
    1499    /**
    1500     * <p>Gets the maximum of three <code>double</code> values.</p>
    1501     *
    1502     * <p>If any value is <code>NaN</code>, <code>NaN</code> is
    1503     * returned. Infinity is handled.</p>
    1504     *
    1505     * @param a  value 1
    1506     * @param b  value 2
    1507     * @param c  value 3
    1508     * @return  the largest of the values
    1509     * @see IEEE754rUtils#max(double, double, double) for a version of this method that handles NaN differently
    1510     */
    1511    public static double max(final double a, final double b, final double c) {
    1512        return Math.max(Math.max(a, b), c);
    1513    }
    1514
    1515    /**
    1516     * <p>Gets the maximum of three <code>float</code> values.</p>
    1517     *
    1518     * <p>If any value is <code>NaN</code>, <code>NaN</code> is
    1519     * returned. Infinity is handled.</p>
    1520     *
    1521     * @param a  value 1
    1522     * @param b  value 2
    1523     * @param c  value 3
    1524     * @return  the largest of the values
    1525     * @see IEEE754rUtils#max(float, float, float) for a version of this method that handles NaN differently
    1526     */
    1527    public static float max(final float a, final float b, final float c) {
    1528        return Math.max(Math.max(a, b), c);
    1529    }
    1530
    1531    //-----------------------------------------------------------------------
    1532    /**
    1533     * <p>Checks whether the <code>String</code> contains only
    1534     * digit characters.</p>
    1535     *
    1536     * <p><code>Null</code> and empty String will return
    1537     * <code>false</code>.</p>
    1538     *
    1539     * @param str  the <code>String</code> to check
    1540     * @return <code>true</code> if str contains only Unicode numeric
    1541     */
    1542    public static boolean isDigits(final String str) {
    1543        return StringUtils.isNumeric(str);
    1544    }
    1545
    1546    /**
    1547     * <p>Checks whether the String a valid Java number.</p>
    1548     *
    1549     * <p>Valid numbers include hexadecimal marked with the <code>0x</code> or
    1550     * <code>0X</code> qualifier, octal numbers, scientific notation and
    1551     * numbers marked with a type qualifier (e.g. 123L).</p>
    1552     *
    1553     * <p>Non-hexadecimal strings beginning with a leading zero are
    1554     * treated as octal values. Thus the string <code>09</code> will return
    1555     * <code>false</code>, since <code>9</code> is not a valid octal value.
    1556     * However, numbers beginning with {@code 0.} are treated as decimal.</p>
    1557     *
    1558     * <p><code>null</code> and empty/blank {@code String} will return
    1559     * <code>false</code>.</p>
    1560     *
    1561     * <p>Note, {@link #createNumber(String)} should return a number for every
    1562     * input resulting in <code>true</code>.</p>
    1563     *
    1564     * @param str  the <code>String</code> to check
    1565     * @return <code>true</code> if the string is a correctly formatted number
    1566     * @since 3.3 the code supports hex {@code 0Xhhh} an
    1567     *        octal {@code 0ddd} validation
    1568     * @deprecated This feature will be removed in Lang 4.0,
    1569     *             use {@link NumberUtils#isCreatable(String)} instead
    1570     */
    1571    @Deprecated
    1572    public static boolean isNumber(final String str) {
    1573        return isCreatable(str);
    1574    }
    1575
    1576    /**
    1577     * <p>Checks whether the String a valid Java number.</p>
    1578     *
    1579     * <p>Valid numbers include hexadecimal marked with the <code>0x</code> or
    1580     * <code>0X</code> qualifier, octal numbers, scientific notation and
    1581     * numbers marked with a type qualifier (e.g. 123L).</p>
    1582     *
    1583     * <p>Non-hexadecimal strings beginning with a leading zero are
    1584     * treated as octal values. Thus the string <code>09</code> will return
    1585     * <code>false</code>, since <code>9</code> is not a valid octal value.
    1586     * However, numbers beginning with {@code 0.} are treated as decimal.</p>
    1587     *
    1588     * <p><code>null</code> and empty/blank {@code String} will return
    1589     * <code>false</code>.</p>
    1590     *
    1591     * <p>Note, {@link #createNumber(String)} should return a number for every
    1592     * input resulting in <code>true</code>.</p>
    1593     *
    1594     * @param str  the <code>String</code> to check
    1595     * @return <code>true</code> if the string is a correctly formatted number
    1596     * @since 3.5
    1597     */
    1598    public static boolean isCreatable(final String str) {
    1599        if (StringUtils.isEmpty(str)) {
    1600            return false;
    1601        }
    1602        final char[] chars = str.toCharArray();
    1603        int sz = chars.length;
    1604        boolean hasExp = false;
    1605        boolean hasDecPoint = false;
    1606        boolean allowSigns = false;
    1607        boolean foundDigit = false;
    1608        // deal with any possible sign up front
    1609        final int start = chars[0] == '-' || chars[0] == '+' ? 1 : 0;
    1610        if (sz > start + 1 && chars[start] == '0' && !StringUtils.contains(str, '.')) { // leading 0, skip if is a decimal number
    1611            if (chars[start + 1] == 'x' || chars[start + 1] == 'X') { // leading 0x/0X
    1612                int i = start + 2;
    1613                if (i == sz) {
    1614                    return false; // str == "0x"
    1615                }
    1616                // checking hex (it can't be anything else)
    1617                for (; i < chars.length; i++) {
    1618                    if ((chars[i] < '0' || chars[i] > '9')
    1619                        && (chars[i] < 'a' || chars[i] > 'f')
    1620                        && (chars[i] < 'A' || chars[i] > 'F')) {
    1621                        return false;
    1622                    }
    1623                }
    1624                return true;
    1625           } else if (Character.isDigit(chars[start + 1])) {
    1626               // leading 0, but not hex, must be octal
    1627               int i = start + 1;
    1628               for (; i < chars.length; i++) {
    1629                   if (chars[i] < '0' || chars[i] > '7') {
    1630                       return false;
    1631                   }
    1632               }
    1633               return true;
    1634           }
    1635        }
    1636        sz--; // don't want to loop to the last char, check it afterwords
    1637              // for type qualifiers
    1638        int i = start;
    1639        // loop to the next to last char or to the last char if we need another digit to
    1640        // make a valid number (e.g. chars[0..5] = "1234E")
    1641        while (i < sz || i < sz + 1 && allowSigns && !foundDigit) {
    1642            if (chars[i] >= '0' && chars[i] <= '9') {
    1643                foundDigit = true;
    1644                allowSigns = false;
    1645
    1646            } else if (chars[i] == '.') {
    1647                if (hasDecPoint || hasExp) {
    1648                    // two decimal points or dec in exponent
    1649                    return false;
    1650                }
    1651                hasDecPoint = true;
    1652            } else if (chars[i] == 'e' || chars[i] == 'E') {
    1653                // we've already taken care of hex.
    1654                if (hasExp) {
    1655                    // two E's
    1656                    return false;
    1657                }
    1658                if (!foundDigit) {
    1659                    return false;
    1660                }
    1661                hasExp = true;
    1662                allowSigns = true;
    1663            } else if (chars[i] == '+' || chars[i] == '-') {
    1664                if (!allowSigns) {
    1665                    return false;
    1666                }
    1667                allowSigns = false;
    1668                foundDigit = false; // we need a digit after the E
    1669            } else {
    1670                return false;
    1671            }
    1672            i++;
    1673        }
    1674        if (i < chars.length) {
    1675            if (chars[i] >= '0' && chars[i] <= '9') {
    1676                // no type qualifier, OK
    1677                return true;
    1678            }
    1679            if (chars[i] == 'e' || chars[i] == 'E') {
    1680                // can't have an E at the last byte
    1681                return false;
    1682            }
    1683            if (chars[i] == '.') {
    1684                if (hasDecPoint || hasExp) {
    1685                    // two decimal points or dec in exponent
    1686                    return false;
    1687                }
    1688                // single trailing decimal point after non-exponent is ok
    1689                return foundDigit;
    1690            }
    1691            if (!allowSigns
    1692                && (chars[i] == 'd'
    1693                    || chars[i] == 'D'
    1694                    || chars[i] == 'f'
    1695                    || chars[i] == 'F')) {
    1696                return foundDigit;
    1697            }
    1698            if (chars[i] == 'l'
    1699                || chars[i] == 'L') {
    1700                // not allowing L with an exponent or decimal point
    1701                return foundDigit && !hasExp && !hasDecPoint;
    1702            }
    1703            // last character is illegal
    1704            return false;
    1705        }
    1706        // allowSigns is true iff the val ends in 'E'
    1707        // found digit it to make sure weird stuff like '.' and '1E-' doesn't pass
    1708        return !allowSigns && foundDigit;
    1709    }
    1710
    1711    /**
    1712     * <p>Checks whether the given String is a parsable number.</p>
    1713     *
    1714     * <p>Parsable numbers include those Strings understood by {@link Integer#parseInt(String)},
    1715     * {@link Long#parseLong(String)}, {@link Float#parseFloat(String)} or
    1716     * {@link Double#parseDouble(String)}. This method can be used instead of catching {@link java.text.ParseException}
    1717     * when calling one of those methods.</p>
    1718     *
    1719     * <p>Hexadecimal and scientific notations are <strong>not</strong> considered parsable.
    1720     * See {@link #isCreatable(String)} on those cases.</p>
    1721     *
    1722     * <p>{@code Null} and empty String will return <code>false</code>.</p>
    1723     *
    1724     * @param str the String to check.
    1725     * @return {@code true} if the string is a parsable number.
    1726     * @since 3.4
    1727     */
    1728    public static boolean isParsable(final String str) {
    1729        if (StringUtils.isEmpty(str)) {
    1730            return false;
    1731        }
    1732        if (str.charAt(str.length() - 1) == '.') {
    1733            return false;
    1734        }
    1735        if (str.charAt(0) == '-') {
    1736            if (str.length() == 1) {
    1737                return false;
    1738            }
    1739            return withDecimalsParsing(str, 1);
    1740        }
    1741        return withDecimalsParsing(str, 0);
    1742    }
    1743
    1744    private static boolean withDecimalsParsing(final String str, final int beginIdx) {
    1745        int decimalPoints = 0;
    1746        for (int i = beginIdx; i < str.length(); i++) {
    1747            final boolean isDecimalPoint = str.charAt(i) == '.';
    1748            if (isDecimalPoint) {
    1749                decimalPoints++;
    1750            }
    1751            if (decimalPoints > 1) {
    1752                return false;
    1753            }
    1754            if (!isDecimalPoint && !Character.isDigit(str.charAt(i))) {
    1755                return false;
    1756            }
    1757        }
    1758        return true;
    1759    }
    1760
    1761    /**
    1762     * <p>Compares two {@code int} values numerically. This is the same functionality as provided in Java 7.</p>
    1763     *
    1764     * @param x the first {@code int} to compare
    1765     * @param y the second {@code int} to compare
    1766     * @return the value {@code 0} if {@code x == y};
    1767     *         a value less than {@code 0} if {@code x < y}; and
    1768     *         a value greater than {@code 0} if {@code x > y}
    1769     * @since 3.4
    1770     */
    1771    public static int compare(final int x, final int y) {
    1772        if (x == y) {
    1773            return 0;
    1774        }
    1775        return x < y ? -1 : 1;
    1776    }
    1777
    1778    /**
    1779     * <p>Compares to {@code long} values numerically. This is the same functionality as provided in Java 7.</p>
    1780     *
    1781     * @param x the first {@code long} to compare
    1782     * @param y the second {@code long} to compare
    1783     * @return the value {@code 0} if {@code x == y};
    1784     *         a value less than {@code 0} if {@code x < y}; and
    1785     *         a value greater than {@code 0} if {@code x > y}
    1786     * @since 3.4
    1787     */
    1788    public static int compare(final long x, final long y) {
    1789        if (x == y) {
    1790            return 0;
    1791        }
    1792        return x < y ? -1 : 1;
    1793    }
    1794
    1795    /**
    1796     * <p>Compares to {@code short} values numerically. This is the same functionality as provided in Java 7.</p>
    1797     *
    1798     * @param x the first {@code short} to compare
    1799     * @param y the second {@code short} to compare
    1800     * @return the value {@code 0} if {@code x == y};
    1801     *         a value less than {@code 0} if {@code x < y}; and
    1802     *         a value greater than {@code 0} if {@code x > y}
    1803     * @since 3.4
    1804     */
    1805    public static int compare(final short x, final short y) {
    1806        if (x == y) {
    1807            return 0;
    1808        }
    1809        return x < y ? -1 : 1;
    1810    }
    1811
    1812    /**
    1813     * <p>Compares two {@code byte} values numerically. This is the same functionality as provided in Java 7.</p>
    1814     *
    1815     * @param x the first {@code byte} to compare
    1816     * @param y the second {@code byte} to compare
    1817     * @return the value {@code 0} if {@code x == y};
    1818     *         a value less than {@code 0} if {@code x < y}; and
    1819     *         a value greater than {@code 0} if {@code x > y}
    1820     * @since 3.4
    1821     */
    1822    public static int compare(final byte x, final byte y) {
    1823        return x - y;
    1824    }
    1825}