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}