0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017: package org.apache.commons.lang.math;
0018:
0019: import java.math.BigDecimal;
0020: import java.math.BigInteger;
0021:
0022: import org.apache.commons.lang.StringUtils;
0023:
0024: /**
0025: * <p>Provides extra functionality for Java Number classes.</p>
0026: *
0027: * @author <a href="mailto:rand_mcneely@yahoo.com">Rand McNeely</a>
0028: * @author Stephen Colebourne
0029: * @author <a href="mailto:steve.downey@netfolio.com">Steve Downey</a>
0030: * @author Eric Pugh
0031: * @author Phil Steitz
0032: * @author Matthew Hawthorne
0033: * @author <a href="mailto:ggregory@seagullsw.com">Gary Gregory</a>
0034: * @author <a href="mailto:fredrik@westermarck.com">Fredrik Westermarck</a>
0035: * @since 2.0
0036: * @version $Id: NumberUtils.java 491076 2006-12-29 18:48:37Z bayard $
0037: */
0038: public class NumberUtils {
0039:
0040: /** Reusable Long constant for zero. */
0041: public static final Long LONG_ZERO = new Long(0L);
0042: /** Reusable Long constant for one. */
0043: public static final Long LONG_ONE = new Long(1L);
0044: /** Reusable Long constant for minus one. */
0045: public static final Long LONG_MINUS_ONE = new Long(-1L);
0046: /** Reusable Integer constant for zero. */
0047: public static final Integer INTEGER_ZERO = new Integer(0);
0048: /** Reusable Integer constant for one. */
0049: public static final Integer INTEGER_ONE = new Integer(1);
0050: /** Reusable Integer constant for minus one. */
0051: public static final Integer INTEGER_MINUS_ONE = new Integer(-1);
0052: /** Reusable Short constant for zero. */
0053: public static final Short SHORT_ZERO = new Short((short) 0);
0054: /** Reusable Short constant for one. */
0055: public static final Short SHORT_ONE = new Short((short) 1);
0056: /** Reusable Short constant for minus one. */
0057: public static final Short SHORT_MINUS_ONE = new Short((short) -1);
0058: /** Reusable Byte constant for zero. */
0059: public static final Byte BYTE_ZERO = new Byte((byte) 0);
0060: /** Reusable Byte constant for one. */
0061: public static final Byte BYTE_ONE = new Byte((byte) 1);
0062: /** Reusable Byte constant for minus one. */
0063: public static final Byte BYTE_MINUS_ONE = new Byte((byte) -1);
0064: /** Reusable Double constant for zero. */
0065: public static final Double DOUBLE_ZERO = new Double(0.0d);
0066: /** Reusable Double constant for one. */
0067: public static final Double DOUBLE_ONE = new Double(1.0d);
0068: /** Reusable Double constant for minus one. */
0069: public static final Double DOUBLE_MINUS_ONE = new Double(-1.0d);
0070: /** Reusable Float constant for zero. */
0071: public static final Float FLOAT_ZERO = new Float(0.0f);
0072: /** Reusable Float constant for one. */
0073: public static final Float FLOAT_ONE = new Float(1.0f);
0074: /** Reusable Float constant for minus one. */
0075: public static final Float FLOAT_MINUS_ONE = new Float(-1.0f);
0076:
0077: /**
0078: * <p><code>NumberUtils</code> instances should NOT be constructed in standard programming.
0079: * Instead, the class should be used as <code>NumberUtils.stringToInt("6");</code>.</p>
0080: *
0081: * <p>This constructor is public to permit tools that require a JavaBean instance
0082: * to operate.</p>
0083: */
0084: public NumberUtils() {
0085: super ();
0086: }
0087:
0088: //-----------------------------------------------------------------------
0089: /**
0090: * <p>Convert a <code>String</code> to an <code>int</code>, returning
0091: * <code>zero</code> if the conversion fails.</p>
0092: *
0093: * <p>If the string is <code>null</code>, <code>zero</code> is returned.</p>
0094: *
0095: * <pre>
0096: * NumberUtils.stringToInt(null) = 0
0097: * NumberUtils.stringToInt("") = 0
0098: * NumberUtils.stringToInt("1") = 1
0099: * </pre>
0100: *
0101: * @param str the string to convert, may be null
0102: * @return the int represented by the string, or <code>zero</code> if
0103: * conversion fails
0104: * @deprecated Use {@link #toInt(String)}
0105: * This method will be removed in Commons Lang 3.0
0106: */
0107: public static int stringToInt(String str) {
0108: return toInt(str);
0109: }
0110:
0111: /**
0112: * <p>Convert a <code>String</code> to an <code>int</code>, returning
0113: * <code>zero</code> if the conversion fails.</p>
0114: *
0115: * <p>If the string is <code>null</code>, <code>zero</code> is returned.</p>
0116: *
0117: * <pre>
0118: * NumberUtils.toInt(null) = 0
0119: * NumberUtils.toInt("") = 0
0120: * NumberUtils.toInt("1") = 1
0121: * </pre>
0122: *
0123: * @param str the string to convert, may be null
0124: * @return the int represented by the string, or <code>zero</code> if
0125: * conversion fails
0126: * @since 2.1
0127: */
0128: public static int toInt(String str) {
0129: return toInt(str, 0);
0130: }
0131:
0132: /**
0133: * <p>Convert a <code>String</code> to an <code>int</code>, returning a
0134: * default value if the conversion fails.</p>
0135: *
0136: * <p>If the string is <code>null</code>, the default value is returned.</p>
0137: *
0138: * <pre>
0139: * NumberUtils.stringToInt(null, 1) = 1
0140: * NumberUtils.stringToInt("", 1) = 1
0141: * NumberUtils.stringToInt("1", 0) = 1
0142: * </pre>
0143: *
0144: * @param str the string to convert, may be null
0145: * @param defaultValue the default value
0146: * @return the int represented by the string, or the default if conversion fails
0147: * @deprecated Use {@link #toInt(String, int)}
0148: * This method will be removed in Commons Lang 3.0
0149: */
0150: public static int stringToInt(String str, int defaultValue) {
0151: return toInt(str, defaultValue);
0152: }
0153:
0154: /**
0155: * <p>Convert a <code>String</code> to an <code>int</code>, returning a
0156: * default value if the conversion fails.</p>
0157: *
0158: * <p>If the string is <code>null</code>, the default value is returned.</p>
0159: *
0160: * <pre>
0161: * NumberUtils.toInt(null, 1) = 1
0162: * NumberUtils.toInt("", 1) = 1
0163: * NumberUtils.toInt("1", 0) = 1
0164: * </pre>
0165: *
0166: * @param str the string to convert, may be null
0167: * @param defaultValue the default value
0168: * @return the int represented by the string, or the default if conversion fails
0169: * @since 2.1
0170: */
0171: public static int toInt(String str, int defaultValue) {
0172: if (str == null) {
0173: return defaultValue;
0174: }
0175: try {
0176: return Integer.parseInt(str);
0177: } catch (NumberFormatException nfe) {
0178: return defaultValue;
0179: }
0180: }
0181:
0182: /**
0183: * <p>Convert a <code>String</code> to a <code>long</code>, returning
0184: * <code>zero</code> if the conversion fails.</p>
0185: *
0186: * <p>If the string is <code>null</code>, <code>zero</code> is returned.</p>
0187: *
0188: * <pre>
0189: * NumberUtils.toLong(null) = 0L
0190: * NumberUtils.toLong("") = 0L
0191: * NumberUtils.toLong("1") = 1L
0192: * </pre>
0193: *
0194: * @param str the string to convert, may be null
0195: * @return the long represented by the string, or <code>0</code> if
0196: * conversion fails
0197: * @since 2.1
0198: */
0199: public static long toLong(String str) {
0200: return toLong(str, 0L);
0201: }
0202:
0203: /**
0204: * <p>Convert a <code>String</code> to a <code>long</code>, returning a
0205: * default value if the conversion fails.</p>
0206: *
0207: * <p>If the string is <code>null</code>, the default value is returned.</p>
0208: *
0209: * <pre>
0210: * NumberUtils.toLong(null, 1L) = 1L
0211: * NumberUtils.toLong("", 1L) = 1L
0212: * NumberUtils.toLong("1", 0L) = 1L
0213: * </pre>
0214: *
0215: * @param str the string to convert, may be null
0216: * @param defaultValue the default value
0217: * @return the long represented by the string, or the default if conversion fails
0218: * @since 2.1
0219: */
0220: public static long toLong(String str, long defaultValue) {
0221: if (str == null) {
0222: return defaultValue;
0223: }
0224: try {
0225: return Long.parseLong(str);
0226: } catch (NumberFormatException nfe) {
0227: return defaultValue;
0228: }
0229: }
0230:
0231: /**
0232: * <p>Convert a <code>String</code> to a <code>float</code>, returning
0233: * <code>0.0f</code> if the conversion fails.</p>
0234: *
0235: * <p>If the string <code>str</code> is <code>null</code>,
0236: * <code>0.0f</code> is returned.</p>
0237: *
0238: * <pre>
0239: * NumberUtils.toFloat(null) = 0.0f
0240: * NumberUtils.toFloat("") = 0.0f
0241: * NumberUtils.toFloat("1.5") = 1.5f
0242: * </pre>
0243: *
0244: * @param str the string to convert, may be <code>null</code>
0245: * @return the float represented by the string, or <code>0.0f</code>
0246: * if conversion fails
0247: * @since 2.1
0248: */
0249: public static float toFloat(String str) {
0250: return toFloat(str, 0.0f);
0251: }
0252:
0253: /**
0254: * <p>Convert a <code>String</code> to a <code>float</code>, returning a
0255: * default value if the conversion fails.</p>
0256: *
0257: * <p>If the string <code>str</code> is <code>null</code>, the default
0258: * value is returned.</p>
0259: *
0260: * <pre>
0261: * NumberUtils.toFloat(null, 1.1f) = 1.0f
0262: * NumberUtils.toFloat("", 1.1f) = 1.1f
0263: * NumberUtils.toFloat("1.5", 0.0f) = 1.5f
0264: * </pre>
0265: *
0266: * @param str the string to convert, may be <code>null</code>
0267: * @param defaultValue the default value
0268: * @return the float represented by the string, or defaultValue
0269: * if conversion fails
0270: * @since 2.1
0271: */
0272: public static float toFloat(String str, float defaultValue) {
0273: if (str == null) {
0274: return defaultValue;
0275: }
0276: try {
0277: return Float.parseFloat(str);
0278: } catch (NumberFormatException nfe) {
0279: return defaultValue;
0280: }
0281: }
0282:
0283: /**
0284: * <p>Convert a <code>String</code> to a <code>double</code>, returning
0285: * <code>0.0d</code> if the conversion fails.</p>
0286: *
0287: * <p>If the string <code>str</code> is <code>null</code>,
0288: * <code>0.0d</code> is returned.</p>
0289: *
0290: * <pre>
0291: * NumberUtils.toDouble(null) = 0.0d
0292: * NumberUtils.toDouble("") = 0.0d
0293: * NumberUtils.toDouble("1.5") = 1.5d
0294: * </pre>
0295: *
0296: * @param str the string to convert, may be <code>null</code>
0297: * @return the double represented by the string, or <code>0.0d</code>
0298: * if conversion fails
0299: * @since 2.1
0300: */
0301: public static double toDouble(String str) {
0302: return toDouble(str, 0.0d);
0303: }
0304:
0305: /**
0306: * <p>Convert a <code>String</code> to a <code>double</code>, returning a
0307: * default value if the conversion fails.</p>
0308: *
0309: * <p>If the string <code>str</code> is <code>null</code>, the default
0310: * value is returned.</p>
0311: *
0312: * <pre>
0313: * NumberUtils.toDouble(null, 1.1d) = 1.1d
0314: * NumberUtils.toDouble("", 1.1d) = 1.1d
0315: * NumberUtils.toDouble("1.5", 0.0d) = 1.5d
0316: * </pre>
0317: *
0318: * @param str the string to convert, may be <code>null</code>
0319: * @param defaultValue the default value
0320: * @return the double represented by the string, or defaultValue
0321: * if conversion fails
0322: * @since 2.1
0323: */
0324: public static double toDouble(String str, double defaultValue) {
0325: if (str == null) {
0326: return defaultValue;
0327: }
0328: try {
0329: return Double.parseDouble(str);
0330: } catch (NumberFormatException nfe) {
0331: return defaultValue;
0332: }
0333: }
0334:
0335: //-----------------------------------------------------------------------
0336: // must handle Long, Float, Integer, Float, Short,
0337: // BigDecimal, BigInteger and Byte
0338: // useful methods:
0339: // Byte.decode(String)
0340: // Byte.valueOf(String,int radix)
0341: // Byte.valueOf(String)
0342: // Double.valueOf(String)
0343: // Float.valueOf(String)
0344: // new Float(String)
0345: // Integer.valueOf(String,int radix)
0346: // Integer.valueOf(String)
0347: // Integer.decode(String)
0348: // Integer.getInteger(String)
0349: // Integer.getInteger(String,int val)
0350: // Integer.getInteger(String,Integer val)
0351: // new Integer(String)
0352: // new Double(String)
0353: // new Byte(String)
0354: // new Long(String)
0355: // Long.getLong(String)
0356: // Long.getLong(String,int)
0357: // Long.getLong(String,Integer)
0358: // Long.valueOf(String,int)
0359: // Long.valueOf(String)
0360: // new Short(String)
0361: // Short.decode(String)
0362: // Short.valueOf(String,int)
0363: // Short.valueOf(String)
0364: // new BigDecimal(String)
0365: // new BigInteger(String)
0366: // new BigInteger(String,int radix)
0367: // Possible inputs:
0368: // 45 45.5 45E7 4.5E7 Hex Oct Binary xxxF xxxD xxxf xxxd
0369: // plus minus everything. Prolly more. A lot are not separable.
0370:
0371: /**
0372: * <p>Turns a string value into a java.lang.Number.</p>
0373: *
0374: * <p>First, the value is examined for a type qualifier on the end
0375: * (<code>'f','F','d','D','l','L'</code>). If it is found, it starts
0376: * trying to create successively larger types from the type specified
0377: * until one is found that can represent the value.</p>
0378: *
0379: * <p>If a type specifier is not found, it will check for a decimal point
0380: * and then try successively larger types from <code>Integer</code> to
0381: * <code>BigInteger</code> and from <code>Float</code> to
0382: * <code>BigDecimal</code>.</p>
0383: *
0384: * <p>If the string starts with <code>0x</code> or <code>-0x</code>, it
0385: * will be interpreted as a hexadecimal integer. Values with leading
0386: * <code>0</code>'s will not be interpreted as octal.</p>
0387: *
0388: * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
0389: *
0390: * <p>This method does not trim the input string, i.e., strings with leading
0391: * or trailing spaces will generate NumberFormatExceptions.</p>
0392: *
0393: * @param str String containing a number, may be null
0394: * @return Number created from the string
0395: * @throws NumberFormatException if the value cannot be converted
0396: */
0397: public static Number createNumber(String str)
0398: throws NumberFormatException {
0399: if (str == null) {
0400: return null;
0401: }
0402: if (StringUtils.isBlank(str)) {
0403: throw new NumberFormatException(
0404: "A blank string is not a valid number");
0405: }
0406: if (str.startsWith("--")) {
0407: // this is protection for poorness in java.lang.BigDecimal.
0408: // it accepts this as a legal value, but it does not appear
0409: // to be in specification of class. OS X Java parses it to
0410: // a wrong value.
0411: return null;
0412: }
0413: if (str.startsWith("0x") || str.startsWith("-0x")) {
0414: return createInteger(str);
0415: }
0416: char lastChar = str.charAt(str.length() - 1);
0417: String mant;
0418: String dec;
0419: String exp;
0420: int decPos = str.indexOf('.');
0421: int expPos = str.indexOf('e') + str.indexOf('E') + 1;
0422:
0423: if (decPos > -1) {
0424:
0425: if (expPos > -1) {
0426: if (expPos < decPos) {
0427: throw new NumberFormatException(str
0428: + " is not a valid number.");
0429: }
0430: dec = str.substring(decPos + 1, expPos);
0431: } else {
0432: dec = str.substring(decPos + 1);
0433: }
0434: mant = str.substring(0, decPos);
0435: } else {
0436: if (expPos > -1) {
0437: mant = str.substring(0, expPos);
0438: } else {
0439: mant = str;
0440: }
0441: dec = null;
0442: }
0443: if (!Character.isDigit(lastChar)) {
0444: if (expPos > -1 && expPos < str.length() - 1) {
0445: exp = str.substring(expPos + 1, str.length() - 1);
0446: } else {
0447: exp = null;
0448: }
0449: //Requesting a specific type..
0450: String numeric = str.substring(0, str.length() - 1);
0451: boolean allZeros = isAllZeros(mant) && isAllZeros(exp);
0452: switch (lastChar) {
0453: case 'l':
0454: case 'L':
0455: if (dec == null
0456: && exp == null
0457: && (numeric.charAt(0) == '-'
0458: && isDigits(numeric.substring(1)) || isDigits(numeric))) {
0459: try {
0460: return createLong(numeric);
0461: } catch (NumberFormatException nfe) {
0462: //Too big for a long
0463: }
0464: return createBigInteger(numeric);
0465:
0466: }
0467: throw new NumberFormatException(str
0468: + " is not a valid number.");
0469: case 'f':
0470: case 'F':
0471: try {
0472: Float f = NumberUtils.createFloat(numeric);
0473: if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) {
0474: //If it's too big for a float or the float value = 0 and the string
0475: //has non-zeros in it, then float does not have the precision we want
0476: return f;
0477: }
0478:
0479: } catch (NumberFormatException nfe) {
0480: // ignore the bad number
0481: }
0482: //Fall through
0483: case 'd':
0484: case 'D':
0485: try {
0486: Double d = NumberUtils.createDouble(numeric);
0487: if (!(d.isInfinite() || (d.floatValue() == 0.0D && !allZeros))) {
0488: return d;
0489: }
0490: } catch (NumberFormatException nfe) {
0491: // ignore the bad number
0492: }
0493: try {
0494: return createBigDecimal(numeric);
0495: } catch (NumberFormatException e) {
0496: // ignore the bad number
0497: }
0498: //Fall through
0499: default:
0500: throw new NumberFormatException(str
0501: + " is not a valid number.");
0502:
0503: }
0504: } else {
0505: //User doesn't have a preference on the return type, so let's start
0506: //small and go from there...
0507: if (expPos > -1 && expPos < str.length() - 1) {
0508: exp = str.substring(expPos + 1, str.length());
0509: } else {
0510: exp = null;
0511: }
0512: if (dec == null && exp == null) {
0513: //Must be an int,long,bigint
0514: try {
0515: return createInteger(str);
0516: } catch (NumberFormatException nfe) {
0517: // ignore the bad number
0518: }
0519: try {
0520: return createLong(str);
0521: } catch (NumberFormatException nfe) {
0522: // ignore the bad number
0523: }
0524: return createBigInteger(str);
0525:
0526: } else {
0527: //Must be a float,double,BigDec
0528: boolean allZeros = isAllZeros(mant) && isAllZeros(exp);
0529: try {
0530: Float f = createFloat(str);
0531: if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) {
0532: return f;
0533: }
0534: } catch (NumberFormatException nfe) {
0535: // ignore the bad number
0536: }
0537: try {
0538: Double d = createDouble(str);
0539: if (!(d.isInfinite() || (d.doubleValue() == 0.0D && !allZeros))) {
0540: return d;
0541: }
0542: } catch (NumberFormatException nfe) {
0543: // ignore the bad number
0544: }
0545:
0546: return createBigDecimal(str);
0547:
0548: }
0549: }
0550: }
0551:
0552: /**
0553: * <p>Utility method for {@link #createNumber(java.lang.String)}.</p>
0554: *
0555: * <p>Returns <code>true</code> if s is <code>null</code>.</p>
0556: *
0557: * @param str the String to check
0558: * @return if it is all zeros or <code>null</code>
0559: */
0560: private static boolean isAllZeros(String str) {
0561: if (str == null) {
0562: return true;
0563: }
0564: for (int i = str.length() - 1; i >= 0; i--) {
0565: if (str.charAt(i) != '0') {
0566: return false;
0567: }
0568: }
0569: return str.length() > 0;
0570: }
0571:
0572: //-----------------------------------------------------------------------
0573: /**
0574: * <p>Convert a <code>String</code> to a <code>Float</code>.</p>
0575: *
0576: * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
0577: *
0578: * @param str a <code>String</code> to convert, may be null
0579: * @return converted <code>Float</code>
0580: * @throws NumberFormatException if the value cannot be converted
0581: */
0582: public static Float createFloat(String str) {
0583: if (str == null) {
0584: return null;
0585: }
0586: return Float.valueOf(str);
0587: }
0588:
0589: /**
0590: * <p>Convert a <code>String</code> to a <code>Double</code>.</p>
0591: *
0592: * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
0593: *
0594: * @param str a <code>String</code> to convert, may be null
0595: * @return converted <code>Double</code>
0596: * @throws NumberFormatException if the value cannot be converted
0597: */
0598: public static Double createDouble(String str) {
0599: if (str == null) {
0600: return null;
0601: }
0602: return Double.valueOf(str);
0603: }
0604:
0605: /**
0606: * <p>Convert a <code>String</code> to a <code>Integer</code>, handling
0607: * hex and octal notations.</p>
0608: *
0609: * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
0610: *
0611: * @param str a <code>String</code> to convert, may be null
0612: * @return converted <code>Integer</code>
0613: * @throws NumberFormatException if the value cannot be converted
0614: */
0615: public static Integer createInteger(String str) {
0616: if (str == null) {
0617: return null;
0618: }
0619: // decode() handles 0xAABD and 0777 (hex and octal) as well.
0620: return Integer.decode(str);
0621: }
0622:
0623: /**
0624: * <p>Convert a <code>String</code> to a <code>Long</code>.</p>
0625: *
0626: * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
0627: *
0628: * @param str a <code>String</code> to convert, may be null
0629: * @return converted <code>Long</code>
0630: * @throws NumberFormatException if the value cannot be converted
0631: */
0632: public static Long createLong(String str) {
0633: if (str == null) {
0634: return null;
0635: }
0636: return Long.valueOf(str);
0637: }
0638:
0639: /**
0640: * <p>Convert a <code>String</code> to a <code>BigInteger</code>.</p>
0641: *
0642: * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
0643: *
0644: * @param str a <code>String</code> to convert, may be null
0645: * @return converted <code>BigInteger</code>
0646: * @throws NumberFormatException if the value cannot be converted
0647: */
0648: public static BigInteger createBigInteger(String str) {
0649: if (str == null) {
0650: return null;
0651: }
0652: return new BigInteger(str);
0653: }
0654:
0655: /**
0656: * <p>Convert a <code>String</code> to a <code>BigDecimal</code>.</p>
0657: *
0658: * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
0659: *
0660: * @param str a <code>String</code> to convert, may be null
0661: * @return converted <code>BigDecimal</code>
0662: * @throws NumberFormatException if the value cannot be converted
0663: */
0664: public static BigDecimal createBigDecimal(String str) {
0665: if (str == null) {
0666: return null;
0667: }
0668: // handle JDK1.3.1 bug where "" throws IndexOutOfBoundsException
0669: if (StringUtils.isBlank(str)) {
0670: throw new NumberFormatException(
0671: "A blank string is not a valid number");
0672: }
0673: return new BigDecimal(str);
0674: }
0675:
0676: // Min in array
0677: //--------------------------------------------------------------------
0678: /**
0679: * <p>Returns the minimum value in an array.</p>
0680: *
0681: * @param array an array, must not be null or empty
0682: * @return the minimum value in the array
0683: * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
0684: * @throws IllegalArgumentException if <code>array</code> is empty
0685: */
0686: public static long min(long[] array) {
0687: // Validates input
0688: if (array == null) {
0689: throw new IllegalArgumentException(
0690: "The Array must not be null");
0691: } else if (array.length == 0) {
0692: throw new IllegalArgumentException("Array cannot be empty.");
0693: }
0694:
0695: // Finds and returns min
0696: long min = array[0];
0697: for (int i = 1; i < array.length; i++) {
0698: if (array[i] < min) {
0699: min = array[i];
0700: }
0701: }
0702:
0703: return min;
0704: }
0705:
0706: /**
0707: * <p>Returns the minimum value in an array.</p>
0708: *
0709: * @param array an array, must not be null or empty
0710: * @return the minimum value in the array
0711: * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
0712: * @throws IllegalArgumentException if <code>array</code> is empty
0713: */
0714: public static int min(int[] array) {
0715: // Validates input
0716: if (array == null) {
0717: throw new IllegalArgumentException(
0718: "The Array must not be null");
0719: } else if (array.length == 0) {
0720: throw new IllegalArgumentException("Array cannot be empty.");
0721: }
0722:
0723: // Finds and returns min
0724: int min = array[0];
0725: for (int j = 1; j < array.length; j++) {
0726: if (array[j] < min) {
0727: min = array[j];
0728: }
0729: }
0730:
0731: return min;
0732: }
0733:
0734: /**
0735: * <p>Returns the minimum value in an array.</p>
0736: *
0737: * @param array an array, must not be null or empty
0738: * @return the minimum value in the array
0739: * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
0740: * @throws IllegalArgumentException if <code>array</code> is empty
0741: */
0742: public static short min(short[] array) {
0743: // Validates input
0744: if (array == null) {
0745: throw new IllegalArgumentException(
0746: "The Array must not be null");
0747: } else if (array.length == 0) {
0748: throw new IllegalArgumentException("Array cannot be empty.");
0749: }
0750:
0751: // Finds and returns min
0752: short min = array[0];
0753: for (int i = 1; i < array.length; i++) {
0754: if (array[i] < min) {
0755: min = array[i];
0756: }
0757: }
0758:
0759: return min;
0760: }
0761:
0762: /**
0763: * <p>Returns the minimum value in an array.</p>
0764: *
0765: * @param array an array, must not be null or empty
0766: * @return the minimum value in the array
0767: * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
0768: * @throws IllegalArgumentException if <code>array</code> is empty
0769: */
0770: public static byte min(byte[] array) {
0771: // Validates input
0772: if (array == null) {
0773: throw new IllegalArgumentException(
0774: "The Array must not be null");
0775: } else if (array.length == 0) {
0776: throw new IllegalArgumentException("Array cannot be empty.");
0777: }
0778:
0779: // Finds and returns min
0780: byte min = array[0];
0781: for (int i = 1; i < array.length; i++) {
0782: if (array[i] < min) {
0783: min = array[i];
0784: }
0785: }
0786:
0787: return min;
0788: }
0789:
0790: /**
0791: * <p>Returns the minimum value in an array.</p>
0792: *
0793: * @param array an array, must not be null or empty
0794: * @return the minimum value in the array
0795: * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
0796: * @throws IllegalArgumentException if <code>array</code> is empty
0797: */
0798: public static double min(double[] array) {
0799: // Validates input
0800: if (array == null) {
0801: throw new IllegalArgumentException(
0802: "The Array must not be null");
0803: } else if (array.length == 0) {
0804: throw new IllegalArgumentException("Array cannot be empty.");
0805: }
0806:
0807: // Finds and returns min
0808: double min = array[0];
0809: for (int i = 1; i < array.length; i++) {
0810: if (array[i] < min) {
0811: min = array[i];
0812: }
0813: }
0814:
0815: return min;
0816: }
0817:
0818: /**
0819: * <p>Returns the minimum value in an array.</p>
0820: *
0821: * @param array an array, must not be null or empty
0822: * @return the minimum value in the array
0823: * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
0824: * @throws IllegalArgumentException if <code>array</code> is empty
0825: */
0826: public static float min(float[] array) {
0827: // Validates input
0828: if (array == null) {
0829: throw new IllegalArgumentException(
0830: "The Array must not be null");
0831: } else if (array.length == 0) {
0832: throw new IllegalArgumentException("Array cannot be empty.");
0833: }
0834:
0835: // Finds and returns min
0836: float min = array[0];
0837: for (int i = 1; i < array.length; i++) {
0838: if (array[i] < min) {
0839: min = array[i];
0840: }
0841: }
0842:
0843: return min;
0844: }
0845:
0846: // Max in array
0847: //--------------------------------------------------------------------
0848: /**
0849: * <p>Returns the maximum value in an array.</p>
0850: *
0851: * @param array an array, must not be null or empty
0852: * @return the minimum value in the array
0853: * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
0854: * @throws IllegalArgumentException if <code>array</code> is empty
0855: */
0856: public static long max(long[] array) {
0857: // Validates input
0858: if (array == null) {
0859: throw new IllegalArgumentException(
0860: "The Array must not be null");
0861: } else if (array.length == 0) {
0862: throw new IllegalArgumentException("Array cannot be empty.");
0863: }
0864:
0865: // Finds and returns max
0866: long max = array[0];
0867: for (int j = 1; j < array.length; j++) {
0868: if (array[j] > max) {
0869: max = array[j];
0870: }
0871: }
0872:
0873: return max;
0874: }
0875:
0876: /**
0877: * <p>Returns the maximum value in an array.</p>
0878: *
0879: * @param array an array, must not be null or empty
0880: * @return the minimum value in the array
0881: * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
0882: * @throws IllegalArgumentException if <code>array</code> is empty
0883: */
0884: public static int max(int[] array) {
0885: // Validates input
0886: if (array == null) {
0887: throw new IllegalArgumentException(
0888: "The Array must not be null");
0889: } else if (array.length == 0) {
0890: throw new IllegalArgumentException("Array cannot be empty.");
0891: }
0892:
0893: // Finds and returns max
0894: int max = array[0];
0895: for (int j = 1; j < array.length; j++) {
0896: if (array[j] > max) {
0897: max = array[j];
0898: }
0899: }
0900:
0901: return max;
0902: }
0903:
0904: /**
0905: * <p>Returns the maximum value in an array.</p>
0906: *
0907: * @param array an array, must not be null or empty
0908: * @return the minimum value in the array
0909: * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
0910: * @throws IllegalArgumentException if <code>array</code> is empty
0911: */
0912: public static short max(short[] array) {
0913: // Validates input
0914: if (array == null) {
0915: throw new IllegalArgumentException(
0916: "The Array must not be null");
0917: } else if (array.length == 0) {
0918: throw new IllegalArgumentException("Array cannot be empty.");
0919: }
0920:
0921: // Finds and returns max
0922: short max = array[0];
0923: for (int i = 1; i < array.length; i++) {
0924: if (array[i] > max) {
0925: max = array[i];
0926: }
0927: }
0928:
0929: return max;
0930: }
0931:
0932: /**
0933: * <p>Returns the maximum value in an array.</p>
0934: *
0935: * @param array an array, must not be null or empty
0936: * @return the minimum value in the array
0937: * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
0938: * @throws IllegalArgumentException if <code>array</code> is empty
0939: */
0940: public static byte max(byte[] array) {
0941: // Validates input
0942: if (array == null) {
0943: throw new IllegalArgumentException(
0944: "The Array must not be null");
0945: } else if (array.length == 0) {
0946: throw new IllegalArgumentException("Array cannot be empty.");
0947: }
0948:
0949: // Finds and returns max
0950: byte max = array[0];
0951: for (int i = 1; i < array.length; i++) {
0952: if (array[i] > max) {
0953: max = array[i];
0954: }
0955: }
0956:
0957: return max;
0958: }
0959:
0960: /**
0961: * <p>Returns the maximum value in an array.</p>
0962: *
0963: * @param array an array, must not be null or empty
0964: * @return the minimum value in the array
0965: * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
0966: * @throws IllegalArgumentException if <code>array</code> is empty
0967: */
0968: public static double max(double[] array) {
0969: // Validates input
0970: if (array == null) {
0971: throw new IllegalArgumentException(
0972: "The Array must not be null");
0973: } else if (array.length == 0) {
0974: throw new IllegalArgumentException("Array cannot be empty.");
0975: }
0976:
0977: // Finds and returns max
0978: double max = array[0];
0979: for (int j = 1; j < array.length; j++) {
0980: if (array[j] > max) {
0981: max = array[j];
0982: }
0983: }
0984:
0985: return max;
0986: }
0987:
0988: /**
0989: * <p>Returns the maximum value in an array.</p>
0990: *
0991: * @param array an array, must not be null or empty
0992: * @return the minimum value in the array
0993: * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
0994: * @throws IllegalArgumentException if <code>array</code> is empty
0995: */
0996: public static float max(float[] array) {
0997: // Validates input
0998: if (array == null) {
0999: throw new IllegalArgumentException(
1000: "The Array must not be null");
1001: } else if (array.length == 0) {
1002: throw new IllegalArgumentException("Array cannot be empty.");
1003: }
1004:
1005: // Finds and returns max
1006: float max = array[0];
1007: for (int j = 1; j < array.length; j++) {
1008: if (array[j] > max) {
1009: max = array[j];
1010: }
1011: }
1012:
1013: return max;
1014: }
1015:
1016: // 3 param min
1017: //-----------------------------------------------------------------------
1018: /**
1019: * <p>Gets the minimum of three <code>long</code> values.</p>
1020: *
1021: * @param a value 1
1022: * @param b value 2
1023: * @param c value 3
1024: * @return the smallest of the values
1025: */
1026: public static long min(long a, long b, long c) {
1027: if (b < a) {
1028: a = b;
1029: }
1030: if (c < a) {
1031: a = c;
1032: }
1033: return a;
1034: }
1035:
1036: /**
1037: * <p>Gets the minimum of three <code>int</code> values.</p>
1038: *
1039: * @param a value 1
1040: * @param b value 2
1041: * @param c value 3
1042: * @return the smallest of the values
1043: */
1044: public static int min(int a, int b, int c) {
1045: if (b < a) {
1046: a = b;
1047: }
1048: if (c < a) {
1049: a = c;
1050: }
1051: return a;
1052: }
1053:
1054: /**
1055: * <p>Gets the minimum of three <code>short</code> values.</p>
1056: *
1057: * @param a value 1
1058: * @param b value 2
1059: * @param c value 3
1060: * @return the smallest of the values
1061: */
1062: public static short min(short a, short b, short c) {
1063: if (b < a) {
1064: a = b;
1065: }
1066: if (c < a) {
1067: a = c;
1068: }
1069: return a;
1070: }
1071:
1072: /**
1073: * <p>Gets the minimum of three <code>byte</code> values.</p>
1074: *
1075: * @param a value 1
1076: * @param b value 2
1077: * @param c value 3
1078: * @return the smallest of the values
1079: */
1080: public static byte min(byte a, byte b, byte c) {
1081: if (b < a) {
1082: a = b;
1083: }
1084: if (c < a) {
1085: a = c;
1086: }
1087: return a;
1088: }
1089:
1090: /**
1091: * <p>Gets the minimum of three <code>double</code> values.</p>
1092: *
1093: * <p>If any value is <code>NaN</code>, <code>NaN</code> is
1094: * returned. Infinity is handled.</p>
1095: *
1096: * @param a value 1
1097: * @param b value 2
1098: * @param c value 3
1099: * @return the smallest of the values
1100: */
1101: public static double min(double a, double b, double c) {
1102: return Math.min(Math.min(a, b), c);
1103: }
1104:
1105: /**
1106: * <p>Gets the minimum of three <code>float</code> values.</p>
1107: *
1108: * <p>If any value is <code>NaN</code>, <code>NaN</code> is
1109: * returned. Infinity is handled.</p>
1110: *
1111: * @param a value 1
1112: * @param b value 2
1113: * @param c value 3
1114: * @return the smallest of the values
1115: */
1116: public static float min(float a, float b, float c) {
1117: return Math.min(Math.min(a, b), c);
1118: }
1119:
1120: // 3 param max
1121: //-----------------------------------------------------------------------
1122: /**
1123: * <p>Gets the maximum of three <code>long</code> values.</p>
1124: *
1125: * @param a value 1
1126: * @param b value 2
1127: * @param c value 3
1128: * @return the largest of the values
1129: */
1130: public static long max(long a, long b, long c) {
1131: if (b > a) {
1132: a = b;
1133: }
1134: if (c > a) {
1135: a = c;
1136: }
1137: return a;
1138: }
1139:
1140: /**
1141: * <p>Gets the maximum of three <code>int</code> values.</p>
1142: *
1143: * @param a value 1
1144: * @param b value 2
1145: * @param c value 3
1146: * @return the largest of the values
1147: */
1148: public static int max(int a, int b, int c) {
1149: if (b > a) {
1150: a = b;
1151: }
1152: if (c > a) {
1153: a = c;
1154: }
1155: return a;
1156: }
1157:
1158: /**
1159: * <p>Gets the maximum of three <code>short</code> values.</p>
1160: *
1161: * @param a value 1
1162: * @param b value 2
1163: * @param c value 3
1164: * @return the largest of the values
1165: */
1166: public static short max(short a, short b, short c) {
1167: if (b > a) {
1168: a = b;
1169: }
1170: if (c > a) {
1171: a = c;
1172: }
1173: return a;
1174: }
1175:
1176: /**
1177: * <p>Gets the maximum of three <code>byte</code> values.</p>
1178: *
1179: * @param a value 1
1180: * @param b value 2
1181: * @param c value 3
1182: * @return the largest of the values
1183: */
1184: public static byte max(byte a, byte b, byte c) {
1185: if (b > a) {
1186: a = b;
1187: }
1188: if (c > a) {
1189: a = c;
1190: }
1191: return a;
1192: }
1193:
1194: /**
1195: * <p>Gets the maximum of three <code>double</code> values.</p>
1196: *
1197: * <p>If any value is <code>NaN</code>, <code>NaN</code> is
1198: * returned. Infinity is handled.</p>
1199: *
1200: * @param a value 1
1201: * @param b value 2
1202: * @param c value 3
1203: * @return the largest of the values
1204: */
1205: public static double max(double a, double b, double c) {
1206: return Math.max(Math.max(a, b), c);
1207: }
1208:
1209: /**
1210: * <p>Gets the maximum of three <code>float</code> values.</p>
1211: *
1212: * <p>If any value is <code>NaN</code>, <code>NaN</code> is
1213: * returned. Infinity is handled.</p>
1214: *
1215: * @param a value 1
1216: * @param b value 2
1217: * @param c value 3
1218: * @return the largest of the values
1219: */
1220: public static float max(float a, float b, float c) {
1221: return Math.max(Math.max(a, b), c);
1222: }
1223:
1224: //-----------------------------------------------------------------------
1225: /**
1226: * <p>Compares two <code>doubles</code> for order.</p>
1227: *
1228: * <p>This method is more comprehensive than the standard Java greater
1229: * than, less than and equals operators.</p>
1230: * <ul>
1231: * <li>It returns <code>-1</code> if the first value is less than the second.</li>
1232: * <li>It returns <code>+1</code> if the first value is greater than the second.</li>
1233: * <li>It returns <code>0</code> if the values are equal.</li>
1234: * </ul>
1235: *
1236: * <p>
1237: * The ordering is as follows, largest to smallest:
1238: * <ul>
1239: * <li>NaN
1240: * <li>Positive infinity
1241: * <li>Maximum double
1242: * <li>Normal positive numbers
1243: * <li>+0.0
1244: * <li>-0.0
1245: * <li>Normal negative numbers
1246: * <li>Minimum double (<code>-Double.MAX_VALUE</code>)
1247: * <li>Negative infinity
1248: * </ul>
1249: * </p>
1250: *
1251: * <p>Comparing <code>NaN</code> with <code>NaN</code> will
1252: * return <code>0</code>.</p>
1253: *
1254: * @param lhs the first <code>double</code>
1255: * @param rhs the second <code>double</code>
1256: * @return <code>-1</code> if lhs is less, <code>+1</code> if greater,
1257: * <code>0</code> if equal to rhs
1258: */
1259: public static int compare(double lhs, double rhs) {
1260: if (lhs < rhs) {
1261: return -1;
1262: }
1263: if (lhs > rhs) {
1264: return +1;
1265: }
1266: // Need to compare bits to handle 0.0 == -0.0 being true
1267: // compare should put -0.0 < +0.0
1268: // Two NaNs are also == for compare purposes
1269: // where NaN == NaN is false
1270: long lhsBits = Double.doubleToLongBits(lhs);
1271: long rhsBits = Double.doubleToLongBits(rhs);
1272: if (lhsBits == rhsBits) {
1273: return 0;
1274: }
1275: // Something exotic! A comparison to NaN or 0.0 vs -0.0
1276: // Fortunately NaN's long is > than everything else
1277: // Also negzeros bits < poszero
1278: // NAN: 9221120237041090560
1279: // MAX: 9218868437227405311
1280: // NEGZERO: -9223372036854775808
1281: if (lhsBits < rhsBits) {
1282: return -1;
1283: } else {
1284: return +1;
1285: }
1286: }
1287:
1288: /**
1289: * <p>Compares two floats for order.</p>
1290: *
1291: * <p>This method is more comprehensive than the standard Java greater than,
1292: * less than and equals operators.</p>
1293: * <ul>
1294: * <li>It returns <code>-1</code> if the first value is less than the second.
1295: * <li>It returns <code>+1</code> if the first value is greater than the second.
1296: * <li>It returns <code>0</code> if the values are equal.
1297: * </ul>
1298: *
1299: * <p> The ordering is as follows, largest to smallest:
1300: * <ul>
1301: * <li>NaN
1302: * <li>Positive infinity
1303: * <li>Maximum float
1304: * <li>Normal positive numbers
1305: * <li>+0.0
1306: * <li>-0.0
1307: * <li>Normal negative numbers
1308: * <li>Minimum float (<code>-Float.MAX_VALUE</code>)
1309: * <li>Negative infinity
1310: * </ul>
1311: *
1312: * <p>Comparing <code>NaN</code> with <code>NaN</code> will return
1313: * <code>0</code>.</p>
1314: *
1315: * @param lhs the first <code>float</code>
1316: * @param rhs the second <code>float</code>
1317: * @return <code>-1</code> if lhs is less, <code>+1</code> if greater,
1318: * <code>0</code> if equal to rhs
1319: */
1320: public static int compare(float lhs, float rhs) {
1321: if (lhs < rhs) {
1322: return -1;
1323: }
1324: if (lhs > rhs) {
1325: return +1;
1326: }
1327: //Need to compare bits to handle 0.0 == -0.0 being true
1328: // compare should put -0.0 < +0.0
1329: // Two NaNs are also == for compare purposes
1330: // where NaN == NaN is false
1331: int lhsBits = Float.floatToIntBits(lhs);
1332: int rhsBits = Float.floatToIntBits(rhs);
1333: if (lhsBits == rhsBits) {
1334: return 0;
1335: }
1336: //Something exotic! A comparison to NaN or 0.0 vs -0.0
1337: //Fortunately NaN's int is > than everything else
1338: //Also negzeros bits < poszero
1339: //NAN: 2143289344
1340: //MAX: 2139095039
1341: //NEGZERO: -2147483648
1342: if (lhsBits < rhsBits) {
1343: return -1;
1344: } else {
1345: return +1;
1346: }
1347: }
1348:
1349: //-----------------------------------------------------------------------
1350: /**
1351: * <p>Checks whether the <code>String</code> contains only
1352: * digit characters.</p>
1353: *
1354: * <p><code>Null</code> and empty String will return
1355: * <code>false</code>.</p>
1356: *
1357: * @param str the <code>String</code> to check
1358: * @return <code>true</code> if str contains only unicode numeric
1359: */
1360: public static boolean isDigits(String str) {
1361: if (StringUtils.isEmpty(str)) {
1362: return false;
1363: }
1364: for (int i = 0; i < str.length(); i++) {
1365: if (!Character.isDigit(str.charAt(i))) {
1366: return false;
1367: }
1368: }
1369: return true;
1370: }
1371:
1372: /**
1373: * <p>Checks whether the String a valid Java number.</p>
1374: *
1375: * <p>Valid numbers include hexadecimal marked with the <code>0x</code>
1376: * qualifier, scientific notation and numbers marked with a type
1377: * qualifier (e.g. 123L).</p>
1378: *
1379: * <p><code>Null</code> and empty String will return
1380: * <code>false</code>.</p>
1381: *
1382: * @param str the <code>String</code> to check
1383: * @return <code>true</code> if the string is a correctly formatted number
1384: */
1385: public static boolean isNumber(String str) {
1386: if (StringUtils.isEmpty(str)) {
1387: return false;
1388: }
1389: char[] chars = str.toCharArray();
1390: int sz = chars.length;
1391: boolean hasExp = false;
1392: boolean hasDecPoint = false;
1393: boolean allowSigns = false;
1394: boolean foundDigit = false;
1395: // deal with any possible sign up front
1396: int start = (chars[0] == '-') ? 1 : 0;
1397: if (sz > start + 1) {
1398: if (chars[start] == '0' && chars[start + 1] == 'x') {
1399: int i = start + 2;
1400: if (i == sz) {
1401: return false; // str == "0x"
1402: }
1403: // checking hex (it can't be anything else)
1404: for (; i < chars.length; i++) {
1405: if ((chars[i] < '0' || chars[i] > '9')
1406: && (chars[i] < 'a' || chars[i] > 'f')
1407: && (chars[i] < 'A' || chars[i] > 'F')) {
1408: return false;
1409: }
1410: }
1411: return true;
1412: }
1413: }
1414: sz--; // don't want to loop to the last char, check it afterwords
1415: // for type qualifiers
1416: int i = start;
1417: // loop to the next to last char or to the last char if we need another digit to
1418: // make a valid number (e.g. chars[0..5] = "1234E")
1419: while (i < sz || (i < sz + 1 && allowSigns && !foundDigit)) {
1420: if (chars[i] >= '0' && chars[i] <= '9') {
1421: foundDigit = true;
1422: allowSigns = false;
1423:
1424: } else if (chars[i] == '.') {
1425: if (hasDecPoint || hasExp) {
1426: // two decimal points or dec in exponent
1427: return false;
1428: }
1429: hasDecPoint = true;
1430: } else if (chars[i] == 'e' || chars[i] == 'E') {
1431: // we've already taken care of hex.
1432: if (hasExp) {
1433: // two E's
1434: return false;
1435: }
1436: if (!foundDigit) {
1437: return false;
1438: }
1439: hasExp = true;
1440: allowSigns = true;
1441: } else if (chars[i] == '+' || chars[i] == '-') {
1442: if (!allowSigns) {
1443: return false;
1444: }
1445: allowSigns = false;
1446: foundDigit = false; // we need a digit after the E
1447: } else {
1448: return false;
1449: }
1450: i++;
1451: }
1452: if (i < chars.length) {
1453: if (chars[i] >= '0' && chars[i] <= '9') {
1454: // no type qualifier, OK
1455: return true;
1456: }
1457: if (chars[i] == 'e' || chars[i] == 'E') {
1458: // can't have an E at the last byte
1459: return false;
1460: }
1461: if (!allowSigns
1462: && (chars[i] == 'd' || chars[i] == 'D'
1463: || chars[i] == 'f' || chars[i] == 'F')) {
1464: return foundDigit;
1465: }
1466: if (chars[i] == 'l' || chars[i] == 'L') {
1467: // not allowing L with an exponent
1468: return foundDigit && !hasExp;
1469: }
1470: // last character is illegal
1471: return false;
1472: }
1473: // allowSigns is true iff the val ends in 'E'
1474: // found digit it to make sure weird stuff like '.' and '1E-' doesn't pass
1475: return !allowSigns && foundDigit;
1476: }
1477:
1478: }
|