1. /* ====================================================================
  2. * The Apache Software License, Version 1.1
  3. *
  4. * Copyright (c) 2002-2003 The Apache Software Foundation. All rights
  5. * reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. *
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in
  16. * the documentation and/or other materials provided with the
  17. * distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution, if
  20. * any, must include the following acknowledgement:
  21. * "This product includes software developed by the
  22. * Apache Software Foundation (http://www.apache.org/)."
  23. * Alternately, this acknowledgement may appear in the software itself,
  24. * if and wherever such third-party acknowledgements normally appear.
  25. *
  26. * 4. The names "The Jakarta Project", "Commons", and "Apache Software
  27. * Foundation" must not be used to endorse or promote products derived
  28. * from this software without prior written permission. For written
  29. * permission, please contact apache@apache.org.
  30. *
  31. * 5. Products derived from this software may not be called "Apache"
  32. * nor may "Apache" appear in their names without prior written
  33. * permission of the Apache Software Foundation.
  34. *
  35. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46. * SUCH DAMAGE.
  47. * ====================================================================
  48. *
  49. * This software consists of voluntary contributions made by many
  50. * individuals on behalf of the Apache Software Foundation. For more
  51. * information on the Apache Software Foundation, please see
  52. * <http://www.apache.org/>.
  53. */
  54. package org.apache.commons.lang.math;
  55. import java.math.BigDecimal;
  56. import java.math.BigInteger;
  57. import org.apache.commons.lang.StringUtils;
  58. /**
  59. * <p>Provides extra functionality for Java Number classes.</p>
  60. *
  61. * @author <a href="mailto:bayard@generationjava.com">Henri Yandell</a>
  62. * @author <a href="mailto:rand_mcneely@yahoo.com">Rand McNeely</a>
  63. * @author Stephen Colebourne
  64. * @author <a href="mailto:steve.downey@netfolio.com">Steve Downey</a>
  65. * @author Eric Pugh
  66. * @author Phil Steitz
  67. * @author Matthew Hawthorne
  68. * @author <a href="mailto:ggregory@seagullsw.com">Gary Gregory</a>
  69. * @since 2.0
  70. * @version $Id: NumberUtils.java,v 1.10 2003/08/18 02:22:24 bayard Exp $
  71. */
  72. public class NumberUtils {
  73. /** Reusable Long constant for zero. */
  74. public static final Long LONG_ZERO = new Long(0L);
  75. /** Reusable Long constant for one. */
  76. public static final Long LONG_ONE = new Long(1L);
  77. /** Reusable Long constant for minus one. */
  78. public static final Long LONG_MINUS_ONE = new Long(-1L);
  79. /** Reusable Integer constant for zero. */
  80. public static final Integer INTEGER_ZERO = new Integer(0);
  81. /** Reusable Integer constant for one. */
  82. public static final Integer INTEGER_ONE = new Integer(1);
  83. /** Reusable Integer constant for minus one. */
  84. public static final Integer INTEGER_MINUS_ONE = new Integer(-1);
  85. /** Reusable Short constant for zero. */
  86. public static final Short SHORT_ZERO = new Short((short) 0);
  87. /** Reusable Short constant for one. */
  88. public static final Short SHORT_ONE = new Short((short) 1);
  89. /** Reusable Short constant for minus one. */
  90. public static final Short SHORT_MINUS_ONE = new Short((short) -1);
  91. /** Reusable Byte constant for zero. */
  92. public static final Byte BYTE_ZERO = new Byte((byte) 0);
  93. /** Reusable Byte constant for one. */
  94. public static final Byte BYTE_ONE = new Byte((byte) 1);
  95. /** Reusable Byte constant for minus one. */
  96. public static final Byte BYTE_MINUS_ONE = new Byte((byte) -1);
  97. /** Reusable Double constant for zero. */
  98. public static final Double DOUBLE_ZERO = new Double(0.0d);
  99. /** Reusable Double constant for one. */
  100. public static final Double DOUBLE_ONE = new Double(1.0d);
  101. /** Reusable Double constant for minus one. */
  102. public static final Double DOUBLE_MINUS_ONE = new Double(-1.0d);
  103. /** Reusable Float constant for zero. */
  104. public static final Float FLOAT_ZERO = new Float(0.0f);
  105. /** Reusable Float constant for one. */
  106. public static final Float FLOAT_ONE = new Float(1.0f);
  107. /** Reusable Float constant for minus one. */
  108. public static final Float FLOAT_MINUS_ONE = new Float(-1.0f);
  109. /**
  110. * <p><code>NumberUtils</code> instances should NOT be constructed in standard programming.
  111. * Instead, the class should be used as <code>NumberUtils.stringToInt("6");</code>.</p>
  112. *
  113. * <p>This constructor is public to permit tools that require a JavaBean instance
  114. * to operate.</p>
  115. */
  116. public NumberUtils() {
  117. }
  118. //-----------------------------------------------------------------------
  119. /**
  120. * <p>Convert a <code>String</code> to an <code>int</code>, returning
  121. * <code>zero</code> if the conversion fails.</p>
  122. *
  123. * <p>If the string is <code>null</code>, <code>zero</code> is returned.</p>
  124. *
  125. * @param str the string to convert, may be null
  126. * @return the int represented by the string, or <code>zero</code> if
  127. * conversion fails
  128. */
  129. public static int stringToInt(String str) {
  130. return stringToInt(str, 0);
  131. }
  132. /**
  133. * <p>Convert a <code>String</code> to an <code>int</code>, returning a
  134. * default value if the conversion fails.</p>
  135. *
  136. * <p>If the string is <code>null</code>, the default value is returned.</p>
  137. *
  138. * @param str the string to convert, may be null
  139. * @param defaultValue the default value
  140. * @return the int represented by the string, or the default if conversion fails
  141. */
  142. public static int stringToInt(String str, int defaultValue) {
  143. try {
  144. return Integer.parseInt(str);
  145. } catch (NumberFormatException nfe) {
  146. return defaultValue;
  147. }
  148. }
  149. //-----------------------------------------------------------------------
  150. // must handle Long, Float, Integer, Float, Short,
  151. // BigDecimal, BigInteger and Byte
  152. // useful methods:
  153. // Byte.decode(String)
  154. // Byte.valueOf(String,int radix)
  155. // Byte.valueOf(String)
  156. // Double.valueOf(String)
  157. // Float.valueOf(String)
  158. // new Float(String)
  159. // Integer.valueOf(String,int radix)
  160. // Integer.valueOf(String)
  161. // Integer.decode(String)
  162. // Integer.getInteger(String)
  163. // Integer.getInteger(String,int val)
  164. // Integer.getInteger(String,Integer val)
  165. // new Integer(String)
  166. // new Double(String)
  167. // new Byte(String)
  168. // new Long(String)
  169. // Long.getLong(String)
  170. // Long.getLong(String,int)
  171. // Long.getLong(String,Integer)
  172. // Long.valueOf(String,int)
  173. // Long.valueOf(String)
  174. // new Short(String)
  175. // Short.decode(String)
  176. // Short.valueOf(String,int)
  177. // Short.valueOf(String)
  178. // new BigDecimal(String)
  179. // new BigInteger(String)
  180. // new BigInteger(String,int radix)
  181. // Possible inputs:
  182. // 45 45.5 45E7 4.5E7 Hex Oct Binary xxxF xxxD xxxf xxxd
  183. // plus minus everything. Prolly more. A lot are not separable.
  184. /**
  185. * <p>Turns a string value into a java.lang.Number.</p>
  186. *
  187. * <p>First, the value is examined for a type qualifier on the end
  188. * (<code>'f','F','d','D','l','L'</code>). If it is found, it starts
  189. * trying to create successively larger types from the type specified
  190. * until one is found that can represent the value.</p>
  191. *
  192. * <p>If a type specifier is not found, it will check for a decimal point
  193. * and then try successively larger types from <code>Integer</code> to
  194. * <code>BigInteger</code> and from <code>Float</code> to
  195. * <code>BigDecimal</code>.</p>
  196. *
  197. * <p>If the string starts with <code>0x</code> or <code>-0x</code>, it
  198. * will be interpreted as a hexadecimal integer. Values with leading
  199. * <code>0</code>'s will not be interpreted as octal.</p>
  200. *
  201. * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
  202. *
  203. * <p>This method does not trim the input string, i.e., strings with leading
  204. * or trailing spaces will generate NumberFormatExceptions.</p>
  205. *
  206. * @param str String containing a number, may be null
  207. * @return Number created from the string
  208. * @throws NumberFormatException if the value cannot be converted
  209. */
  210. public static Number createNumber(String str) throws NumberFormatException {
  211. if (str == null) {
  212. return null;
  213. }
  214. if (StringUtils.isBlank(str)) {
  215. throw new NumberFormatException("A blank string is not a valid number");
  216. }
  217. if (str.startsWith("--")) {
  218. // this is protection for poorness in java.lang.BigDecimal.
  219. // it accepts this as a legal value, but it does not appear
  220. // to be in specification of class. OS X Java parses it to
  221. // a wrong value.
  222. return null;
  223. }
  224. if (str.startsWith("0x") || str.startsWith("-0x")) {
  225. return createInteger(str);
  226. }
  227. char lastChar = str.charAt(str.length() - 1);
  228. String mant;
  229. String dec;
  230. String exp;
  231. int decPos = str.indexOf('.');
  232. int expPos = str.indexOf('e') + str.indexOf('E') + 1;
  233. if (decPos > -1) {
  234. if (expPos > -1) {
  235. if (expPos < decPos) {
  236. throw new NumberFormatException(str + " is not a valid number.");
  237. }
  238. dec = str.substring(decPos + 1, expPos);
  239. } else {
  240. dec = str.substring(decPos + 1);
  241. }
  242. mant = str.substring(0, decPos);
  243. } else {
  244. if (expPos > -1) {
  245. mant = str.substring(0, expPos);
  246. } else {
  247. mant = str;
  248. }
  249. dec = null;
  250. }
  251. if (!Character.isDigit(lastChar)) {
  252. if (expPos > -1 && expPos < str.length() - 1) {
  253. exp = str.substring(expPos + 1, str.length() - 1);
  254. } else {
  255. exp = null;
  256. }
  257. //Requesting a specific type..
  258. String numeric = str.substring(0, str.length() - 1);
  259. boolean allZeros = isAllZeros(mant) && isAllZeros(exp);
  260. switch (lastChar) {
  261. case 'l' :
  262. case 'L' :
  263. if (dec == null
  264. && exp == null
  265. && isDigits(numeric.substring(1))
  266. && (numeric.charAt(0) == '-' || Character.isDigit(numeric.charAt(0)))) {
  267. try {
  268. return createLong(numeric);
  269. } catch (NumberFormatException nfe) {
  270. //Too big for a long
  271. }
  272. return createBigInteger(numeric);
  273. }
  274. throw new NumberFormatException(str + " is not a valid number.");
  275. case 'f' :
  276. case 'F' :
  277. try {
  278. Float f = NumberUtils.createFloat(numeric);
  279. if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) {
  280. //If it's too big for a float or the float value = 0 and the string
  281. //has non-zeros in it, then float doens't have the presision we want
  282. return f;
  283. }
  284. } catch (NumberFormatException nfe) {
  285. }
  286. //Fall through
  287. case 'd' :
  288. case 'D' :
  289. try {
  290. Double d = NumberUtils.createDouble(numeric);
  291. if (!(d.isInfinite() || (d.floatValue() == 0.0D && !allZeros))) {
  292. return d;
  293. }
  294. } catch (NumberFormatException nfe) {
  295. }
  296. try {
  297. return createBigDecimal(numeric);
  298. } catch (NumberFormatException e) {
  299. }
  300. //Fall through
  301. default :
  302. throw new NumberFormatException(str + " is not a valid number.");
  303. }
  304. } else {
  305. //User doesn't have a preference on the return type, so let's start
  306. //small and go from there...
  307. if (expPos > -1 && expPos < str.length() - 1) {
  308. exp = str.substring(expPos + 1, str.length());
  309. } else {
  310. exp = null;
  311. }
  312. if (dec == null && exp == null) {
  313. //Must be an int,long,bigint
  314. try {
  315. return createInteger(str);
  316. } catch (NumberFormatException nfe) {
  317. }
  318. try {
  319. return createLong(str);
  320. } catch (NumberFormatException nfe) {
  321. }
  322. return createBigInteger(str);
  323. } else {
  324. //Must be a float,double,BigDec
  325. boolean allZeros = isAllZeros(mant) && isAllZeros(exp);
  326. try {
  327. Float f = createFloat(str);
  328. if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) {
  329. return f;
  330. }
  331. } catch (NumberFormatException nfe) {
  332. }
  333. try {
  334. Double d = createDouble(str);
  335. if (!(d.isInfinite() || (d.doubleValue() == 0.0D && !allZeros))) {
  336. return d;
  337. }
  338. } catch (NumberFormatException nfe) {
  339. }
  340. return createBigDecimal(str);
  341. }
  342. }
  343. }
  344. /**
  345. * <p>Utility method for {@link #createNumber(java.lang.String)}.</p>
  346. *
  347. * <p>Returns <code>true</code> if s is <code>null</code>.</p>
  348. *
  349. * @param str the String to check
  350. * @return if it is all zeros or <code>null</code>
  351. */
  352. private static boolean isAllZeros(String str) {
  353. if (str == null) {
  354. return true;
  355. }
  356. for (int i = str.length() - 1; i >= 0; i--) {
  357. if (str.charAt(i) != '0') {
  358. return false;
  359. }
  360. }
  361. return str.length() > 0;
  362. }
  363. //-----------------------------------------------------------------------
  364. /**
  365. * <p>Convert a <code>String</code> to a <code>Float</code>.</p>
  366. *
  367. * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
  368. *
  369. * @param str a <code>String</code> to convert, may be null
  370. * @return converted <code>Float</code>
  371. * @throws NumberFormatException if the value cannot be converted
  372. */
  373. public static Float createFloat(String str) {
  374. if (str == null) {
  375. return null;
  376. }
  377. return Float.valueOf(str);
  378. }
  379. /**
  380. * <p>Convert a <code>String</code> to a <code>Double</code>.</p>
  381. *
  382. * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
  383. *
  384. * @param str a <code>String</code> to convert, may be null
  385. * @return converted <code>Double</code>
  386. * @throws NumberFormatException if the value cannot be converted
  387. */
  388. public static Double createDouble(String str) {
  389. if (str == null) {
  390. return null;
  391. }
  392. return Double.valueOf(str);
  393. }
  394. /**
  395. * <p>Convert a <code>String</code> to a <code>Integer</code>, handling
  396. * hex and octal notations.</p>
  397. *
  398. * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
  399. *
  400. * @param str a <code>String</code> to convert, may be null
  401. * @return converted <code>Integer</code>
  402. * @throws NumberFormatException if the value cannot be converted
  403. */
  404. public static Integer createInteger(String str) {
  405. if (str == null) {
  406. return null;
  407. }
  408. // decode() handles 0xAABD and 0777 (hex and octal) as well.
  409. return Integer.decode(str);
  410. }
  411. /**
  412. * <p>Convert a <code>String</code> to a <code>Long</code>.</p>
  413. *
  414. * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
  415. *
  416. * @param str a <code>String</code> to convert, may be null
  417. * @return converted <code>Long</code>
  418. * @throws NumberFormatException if the value cannot be converted
  419. */
  420. public static Long createLong(String str) {
  421. if (str == null) {
  422. return null;
  423. }
  424. return Long.valueOf(str);
  425. }
  426. /**
  427. * <p>Convert a <code>String</code> to a <code>BigInteger</code>.</p>
  428. *
  429. * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
  430. *
  431. * @param str a <code>String</code> to convert, may be null
  432. * @return converted <code>BigInteger</code>
  433. * @throws NumberFormatException if the value cannot be converted
  434. */
  435. public static BigInteger createBigInteger(String str) {
  436. if (str == null) {
  437. return null;
  438. }
  439. return new BigInteger(str);
  440. }
  441. /**
  442. * <p>Convert a <code>String</code> to a <code>BigDecimal</code>.</p>
  443. *
  444. * <p>Returns <code>null</code> if the string is <code>null</code>.</p>
  445. *
  446. * @param str a <code>String</code> to convert, may be null
  447. * @return converted <code>BigDecimal</code>
  448. * @throws NumberFormatException if the value cannot be converted
  449. */
  450. public static BigDecimal createBigDecimal(String str) {
  451. if (str == null) {
  452. return null;
  453. }
  454. // handle JDK1.3.1 bug where "" throws IndexOutOfBoundsException
  455. if (StringUtils.isBlank(str)) {
  456. throw new NumberFormatException("A blank string is not a valid number");
  457. }
  458. return new BigDecimal(str);
  459. }
  460. // Min in array
  461. //--------------------------------------------------------------------
  462. /**
  463. * <p>Returns the minimum value in an array.</p>
  464. *
  465. * @param array an array, must not be null or empty
  466. * @return the minimum value in the array
  467. * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
  468. * @throws IllegalArgumentException if <code>array</code> is empty
  469. */
  470. public static long min(long[] array) {
  471. // Validates input
  472. if (array == null) {
  473. throw new IllegalArgumentException("The Array must not be null");
  474. } else if (array.length == 0) {
  475. throw new IllegalArgumentException("Array cannot be empty.");
  476. }
  477. // Finds and returns min
  478. long min = array[0];
  479. for (int i = 1; i < array.length; i++) {
  480. if (array[i] < min) {
  481. min = array[i];
  482. }
  483. }
  484. return min;
  485. }
  486. /**
  487. * <p>Returns the minimum value in an array.</p>
  488. *
  489. * @param array an array, must not be null or empty
  490. * @return the minimum value in the array
  491. * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
  492. * @throws IllegalArgumentException if <code>array</code> is empty
  493. */
  494. public static int min(int[] array) {
  495. // Validates input
  496. if (array == null) {
  497. throw new IllegalArgumentException("The Array must not be null");
  498. } else if (array.length == 0) {
  499. throw new IllegalArgumentException("Array cannot be empty.");
  500. }
  501. // Finds and returns min
  502. int min = array[0];
  503. for (int j = 1; j < array.length; j++) {
  504. if (array[j] < min) {
  505. min = array[j];
  506. }
  507. }
  508. return min;
  509. }
  510. /**
  511. * <p>Returns the minimum value in an array.</p>
  512. *
  513. * @param array an array, must not be null or empty
  514. * @return the minimum value in the array
  515. * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
  516. * @throws IllegalArgumentException if <code>array</code> is empty
  517. */
  518. public static short min(short[] array) {
  519. // Validates input
  520. if (array == null) {
  521. throw new IllegalArgumentException("The Array must not be null");
  522. } else if (array.length == 0) {
  523. throw new IllegalArgumentException("Array cannot be empty.");
  524. }
  525. // Finds and returns min
  526. short min = array[0];
  527. for (int i = 1; i < array.length; i++) {
  528. if (array[i] < min) {
  529. min = array[i];
  530. }
  531. }
  532. return min;
  533. }
  534. /**
  535. * <p>Returns the minimum value in an array.</p>
  536. *
  537. * @param array an array, must not be null or empty
  538. * @return the minimum value in the array
  539. * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
  540. * @throws IllegalArgumentException if <code>array</code> is empty
  541. */
  542. public static double min(double[] array) {
  543. // Validates input
  544. if (array == null) {
  545. throw new IllegalArgumentException("The Array must not be null");
  546. } else if (array.length == 0) {
  547. throw new IllegalArgumentException("Array cannot be empty.");
  548. }
  549. // Finds and returns min
  550. double min = array[0];
  551. for (int i = 1; i < array.length; i++) {
  552. if (array[i] < min) {
  553. min = array[i];
  554. }
  555. }
  556. return min;
  557. }
  558. /**
  559. * <p>Returns the minimum value in an array.</p>
  560. *
  561. * @param array an array, must not be null or empty
  562. * @return the minimum value in the array
  563. * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
  564. * @throws IllegalArgumentException if <code>array</code> is empty
  565. */
  566. public static float min(float[] array) {
  567. // Validates input
  568. if (array == null) {
  569. throw new IllegalArgumentException("The Array must not be null");
  570. } else if (array.length == 0) {
  571. throw new IllegalArgumentException("Array cannot be empty.");
  572. }
  573. // Finds and returns min
  574. float min = array[0];
  575. for (int i = 1; i < array.length; i++) {
  576. if (array[i] < min) {
  577. min = array[i];
  578. }
  579. }
  580. return min;
  581. }
  582. // Max in array
  583. //--------------------------------------------------------------------
  584. /**
  585. * <p>Returns the maximum value in an array.</p>
  586. *
  587. * @param array an array, must not be null or empty
  588. * @return the minimum value in the array
  589. * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
  590. * @throws IllegalArgumentException if <code>array</code> is empty
  591. */
  592. public static long max(long[] array) {
  593. // Validates input
  594. if (array == null) {
  595. throw new IllegalArgumentException("The Array must not be null");
  596. } else if (array.length == 0) {
  597. throw new IllegalArgumentException("Array cannot be empty.");
  598. }
  599. // Finds and returns max
  600. long max = array[0];
  601. for (int j = 1; j < array.length; j++) {
  602. if (array[j] > max) {
  603. max = array[j];
  604. }
  605. }
  606. return max;
  607. }
  608. /**
  609. * <p>Returns the maximum value in an array.</p>
  610. *
  611. * @param array an array, must not be null or empty
  612. * @return the minimum value in the array
  613. * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
  614. * @throws IllegalArgumentException if <code>array</code> is empty
  615. */
  616. public static int max(int[] array) {
  617. // Validates input
  618. if (array == null) {
  619. throw new IllegalArgumentException("The Array must not be null");
  620. } else if (array.length == 0) {
  621. throw new IllegalArgumentException("Array cannot be empty.");
  622. }
  623. // Finds and returns max
  624. int max = array[0];
  625. for (int j = 1; j < array.length; j++) {
  626. if (array[j] > max) {
  627. max = array[j];
  628. }
  629. }
  630. return max;
  631. }
  632. /**
  633. * <p>Returns the maximum value in an array.</p>
  634. *
  635. * @param array an array, must not be null or empty
  636. * @return the minimum value in the array
  637. * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
  638. * @throws IllegalArgumentException if <code>array</code> is empty
  639. */
  640. public static short max(short[] array) {
  641. // Validates input
  642. if (array == null) {
  643. throw new IllegalArgumentException("The Array must not be null");
  644. } else if (array.length == 0) {
  645. throw new IllegalArgumentException("Array cannot be empty.");
  646. }
  647. // Finds and returns max
  648. short max = array[0];
  649. for (int i = 1; i < array.length; i++) {
  650. if (array[i] > max) {
  651. max = array[i];
  652. }
  653. }
  654. return max;
  655. }
  656. /**
  657. * <p>Returns the maximum value in an array.</p>
  658. *
  659. * @param array an array, must not be null or empty
  660. * @return the minimum value in the array
  661. * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
  662. * @throws IllegalArgumentException if <code>array</code> is empty
  663. */
  664. public static double max(double[] array) {
  665. // Validates input
  666. if (array== null) {
  667. throw new IllegalArgumentException("The Array must not be null");
  668. } else if (array.length == 0) {
  669. throw new IllegalArgumentException("Array cannot be empty.");
  670. }
  671. // Finds and returns max
  672. double max = array[0];
  673. for (int j = 1; j < array.length; j++) {
  674. if (array[j] > max) {
  675. max = array[j];
  676. }
  677. }
  678. return max;
  679. }
  680. /**
  681. * <p>Returns the maximum value in an array.</p>
  682. *
  683. * @param array an array, must not be null or empty
  684. * @return the minimum value in the array
  685. * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
  686. * @throws IllegalArgumentException if <code>array</code> is empty
  687. */
  688. public static float max(float[] array) {
  689. // Validates input
  690. if (array == null) {
  691. throw new IllegalArgumentException("The Array must not be null");
  692. } else if (array.length == 0) {
  693. throw new IllegalArgumentException("Array cannot be empty.");
  694. }
  695. // Finds and returns max
  696. float max = array[0];
  697. for (int j = 1; j < array.length; j++) {
  698. if (array[j] > max) {
  699. max = array[j];
  700. }
  701. }
  702. return max;
  703. }
  704. // 3 param min
  705. //-----------------------------------------------------------------------
  706. /**
  707. * <p>Gets the minimum of three <code>long</code> values.</p>
  708. *
  709. * @param a value 1
  710. * @param b value 2
  711. * @param c value 3
  712. * @return the smallest of the values
  713. */
  714. public static long min(long a, long b, long c) {
  715. if (b < a) {
  716. a = b;
  717. }
  718. if (c < a) {
  719. a = c;
  720. }
  721. return a;
  722. }
  723. /**
  724. * <p>Gets the minimum of three <code>int</code> values.</p>
  725. *
  726. * @param a value 1
  727. * @param b value 2
  728. * @param c value 3
  729. * @return the smallest of the values
  730. */
  731. public static int min(int a, int b, int c) {
  732. if (b < a) {
  733. a = b;
  734. }
  735. if (c < a) {
  736. a = c;
  737. }
  738. return a;
  739. }
  740. /**
  741. * <p>Gets the minimum of three <code>short</code> values.</p>
  742. *
  743. * @param a value 1
  744. * @param b value 2
  745. * @param c value 3
  746. * @return the smallest of the values
  747. */
  748. public static short min(short a, short b, short c) {
  749. if (b < a) {
  750. a = b;
  751. }
  752. if (c < a) {
  753. a = c;
  754. }
  755. return a;
  756. }
  757. /**
  758. * <p>Gets the minimum of three <code>byte</code> values.</p>
  759. *
  760. * @param a value 1
  761. * @param b value 2
  762. * @param c value 3
  763. * @return the smallest of the values
  764. */
  765. public static byte min(byte a, byte b, byte c) {
  766. if (b < a) {
  767. a = b;
  768. }
  769. if (c < a) {
  770. a = c;
  771. }
  772. return a;
  773. }
  774. /**
  775. * <p>Gets the minimum of three <code>double</code> values.</p>
  776. *
  777. * <p>If any value is <code>NaN</code>, <code>NaN</code> is
  778. * returned. Infinity is handled.</p>
  779. *
  780. * @param a value 1
  781. * @param b value 2
  782. * @param c value 3
  783. * @return the smallest of the values
  784. */
  785. public static double min(double a, double b, double c) {
  786. return Math.min(Math.min(a, b), c);
  787. }
  788. /**
  789. * <p>Gets the minimum of three <code>float</code> values.</p>
  790. *
  791. * <p>If any value is <code>NaN</code>, <code>NaN</code> is
  792. * returned. Infinity is handled.</p>
  793. *
  794. * @param a value 1
  795. * @param b value 2
  796. * @param c value 3
  797. * @return the smallest of the values
  798. */
  799. public static float min(float a, float b, float c) {
  800. return Math.min(Math.min(a, b), c);
  801. }
  802. // 3 param max
  803. //-----------------------------------------------------------------------
  804. /**
  805. * <p>Gets the maximum of three <code>long</code> values.</p>
  806. *
  807. * @param a value 1
  808. * @param b value 2
  809. * @param c value 3
  810. * @return the largest of the values
  811. */
  812. public static long max(long a, long b, long c) {
  813. if (b > a) {
  814. a = b;
  815. }
  816. if (c > a) {
  817. a = c;
  818. }
  819. return a;
  820. }
  821. /**
  822. * <p>Gets the maximum of three <code>int</code> values.</p>
  823. *
  824. * @param a value 1
  825. * @param b value 2
  826. * @param c value 3
  827. * @return the largest of the values
  828. */
  829. public static int max(int a, int b, int c) {
  830. if (b > a) {
  831. a = b;
  832. }
  833. if (c > a) {
  834. a = c;
  835. }
  836. return a;
  837. }
  838. /**
  839. * <p>Gets the maximum of three <code>short</code> values.</p>
  840. *
  841. * @param a value 1
  842. * @param b value 2
  843. * @param c value 3
  844. * @return the largest of the values
  845. */
  846. public static short max(short a, short b, short c) {
  847. if (b > a) {
  848. a = b;
  849. }
  850. if (c > a) {
  851. a = c;
  852. }
  853. return a;
  854. }
  855. /**
  856. * <p>Gets the maximum of three <code>byte</code> values.</p>
  857. *
  858. * @param a value 1
  859. * @param b value 2
  860. * @param c value 3
  861. * @return the largest of the values
  862. */
  863. public static byte max(byte a, byte b, byte c) {
  864. if (b > a) {
  865. a = b;
  866. }
  867. if (c > a) {
  868. a = c;
  869. }
  870. return a;
  871. }
  872. /**
  873. * <p>Gets the maximum of three <code>double</code> values.</p>
  874. *
  875. * <p>If any value is <code>NaN</code>, <code>NaN</code> is
  876. * returned. Infinity is handled.</p>
  877. *
  878. * @param a value 1
  879. * @param b value 2
  880. * @param c value 3
  881. * @return the largest of the values
  882. */
  883. public static double max(double a, double b, double c) {
  884. return Math.max(Math.max(a, b), c);
  885. }
  886. /**
  887. * <p>Gets the maximum of three <code>float</code> values.</p>
  888. *
  889. * <p>If any value is <code>NaN</code>, <code>NaN</code> is
  890. * returned. Infinity is handled.</p>
  891. *
  892. * @param a value 1
  893. * @param b value 2
  894. * @param c value 3
  895. * @return the largest of the values
  896. */
  897. public static float max(float a, float b, float c) {
  898. return Math.max(Math.max(a, b), c);
  899. }
  900. //-----------------------------------------------------------------------
  901. /**
  902. * <p>Compares two <code>doubles</code> for order.</p>
  903. *
  904. * <p>This method is more comprehensive than the standard Java greater
  905. * than, less than and equals operators.</p>
  906. * <ul>
  907. * <li>It returns <code>-1</code> if the first value is less than the second.</li>
  908. * <li>It returns <code>+1</code> if the first value is greater than the second.</li>
  909. * <li>It returns <code>0</code> if the values are equal.</li>
  910. * </ul>
  911. *
  912. * <p>
  913. * The ordering is as follows, largest to smallest:
  914. * <ul>
  915. * <li>NaN
  916. * <li>Positive infinity
  917. * <li>Maximum double
  918. * <li>Normal positve numbers
  919. * <li>+0.0
  920. * <li>-0.0
  921. * <li>Normal negative numbers
  922. * <li>Minimum double (<code>-Double.MAX_VALUE</code>)
  923. * <li>Negative infinity
  924. * </ul>
  925. * </p>
  926. *
  927. * <p>Comparing <code>NaN</code> with <code>NaN</code> will
  928. * return <code>0</code>.</p>
  929. *
  930. * @param lhs the first <code>double</code>
  931. * @param rhs the second <code>double</code>
  932. * @return <code>-1</code> if lhs is less, <code>+1</code> if greater,
  933. * <code>0</code> if equal to rhs
  934. */
  935. public static int compare(double lhs, double rhs) {
  936. if (lhs < rhs) {
  937. return -1;
  938. }
  939. if (lhs > rhs) {
  940. return +1;
  941. }
  942. // Need to compare bits to handle 0.0 == -0.0 being true
  943. // compare should put -0.0 < +0.0
  944. // Two NaNs are also == for compare purposes
  945. // where NaN == NaN is false
  946. long lhsBits = Double.doubleToLongBits(lhs);
  947. long rhsBits = Double.doubleToLongBits(rhs);
  948. if (lhsBits == rhsBits) {
  949. return 0;
  950. }
  951. // Something exotic! A comparison to NaN or 0.0 vs -0.0
  952. // Fortunately NaN's long is > than everything else
  953. // Also negzeros bits < poszero
  954. // NAN: 9221120237041090560
  955. // MAX: 9218868437227405311
  956. // NEGZERO: -9223372036854775808
  957. if (lhsBits < rhsBits) {
  958. return -1;
  959. } else {
  960. return +1;
  961. }
  962. }
  963. /**
  964. * <p>Compares two floats for order.</p>
  965. *
  966. * <p>This method is more comprhensive than the standard Java greater than,
  967. * less than and equals operators.</p>
  968. * <ul>
  969. * <li>It returns <code>-1</code> if the first value is less than the second.
  970. * <li>It returns <code>+1</code> if the first value is greater than the second.
  971. * <li>It returns <code>0</code> if the values are equal.
  972. * </ul>
  973. *
  974. * <p> The ordering is as follows, largest to smallest:
  975. * <ul>
  976. * <li>NaN
  977. * <li>Positive infinity
  978. * <li>Maximum float
  979. * <li>Normal positve numbers
  980. * <li>+0.0
  981. * <li>-0.0
  982. * <li>Normal negative numbers
  983. * <li>Minimum float (<code>-Float.MAX_VALUE</code>)
  984. * <li>Negative infinity
  985. * </ul>
  986. *
  987. * <p>Comparing <code>NaN</code> with <code>NaN</code> will return
  988. * <code>0</code>.</p>
  989. *
  990. * @param lhs the first <code>float</code>
  991. * @param rhs the second <code>float</code>
  992. * @return <code>-1</code> if lhs is less, <code>+1</code> if greater,
  993. * <code>0</code> if equal to rhs
  994. */
  995. public static int compare(float lhs, float rhs) {
  996. if (lhs < rhs) {
  997. return -1;
  998. }
  999. if (lhs > rhs) {
  1000. return +1;
  1001. }
  1002. //Need to compare bits to handle 0.0 == -0.0 being true
  1003. // compare should put -0.0 < +0.0
  1004. // Two NaNs are also == for compare purposes
  1005. // where NaN == NaN is false
  1006. int lhsBits = Float.floatToIntBits(lhs);
  1007. int rhsBits = Float.floatToIntBits(rhs);
  1008. if (lhsBits == rhsBits) {
  1009. return 0;
  1010. }
  1011. //Something exotic! A comparison to NaN or 0.0 vs -0.0
  1012. //Fortunately NaN's int is > than everything else
  1013. //Also negzeros bits < poszero
  1014. //NAN: 2143289344
  1015. //MAX: 2139095039
  1016. //NEGZERO: -2147483648
  1017. if (lhsBits < rhsBits) {
  1018. return -1;
  1019. } else {
  1020. return +1;
  1021. }
  1022. }
  1023. //-----------------------------------------------------------------------
  1024. /**
  1025. * <p>Checks whether the <code>String</code> contains only
  1026. * digit characters.</p>
  1027. *
  1028. * <p><code>Null</code> and empty String will return
  1029. * <code>false</code>.</p>
  1030. *
  1031. * @param str the <code>String</code> to check
  1032. * @return <code>true</code> if str contains only unicode numeric
  1033. */
  1034. public static boolean isDigits(String str) {
  1035. if ((str == null) || (str.length() == 0)) {
  1036. return false;
  1037. }
  1038. for (int i = 0; i < str.length(); i++) {
  1039. if (!Character.isDigit(str.charAt(i))) {
  1040. return false;
  1041. }
  1042. }
  1043. return true;
  1044. }
  1045. /**
  1046. * <p>Checks whether the String a valid Java number.</p>
  1047. *
  1048. * <p>Valid numbers include hexadecimal marked with the <code>0x</code>
  1049. * qualifier, scientific notation and numbers marked with a type
  1050. * qualifier (e.g. 123L).</p>
  1051. *
  1052. * <p><code>Null</code> and empty String will return
  1053. * <code>false</code>.</p>
  1054. *
  1055. * @param str the <code>String</code> to check
  1056. * @return <code>true</code> if the string is a correctly formatted number
  1057. */
  1058. public static boolean isNumber(String str) {
  1059. if ((str == null) || (str.length() == 0)) {
  1060. return false;
  1061. }
  1062. char[] chars = str.toCharArray();
  1063. int sz = chars.length;
  1064. boolean hasExp = false;
  1065. boolean hasDecPoint = false;
  1066. boolean allowSigns = false;
  1067. boolean foundDigit = false;
  1068. // deal with any possible sign up front
  1069. int start = (chars[0] == '-') ? 1 : 0;
  1070. if (sz > start + 1) {
  1071. if (chars[start] == '0' && chars[start + 1] == 'x') {
  1072. int i = start + 2;
  1073. if (i == sz) {
  1074. return false; // str == "0x"
  1075. }
  1076. // checking hex (it can't be anything else)
  1077. for (; i < chars.length; i++) {
  1078. if ((chars[i] < '0' || chars[i] > '9')
  1079. && (chars[i] < 'a' || chars[i] > 'f')
  1080. && (chars[i] < 'A' || chars[i] > 'F')) {
  1081. return false;
  1082. }
  1083. }
  1084. return true;
  1085. }
  1086. }
  1087. sz--; // don't want to loop to the last char, check it afterwords
  1088. // for type qualifiers
  1089. int i = start;
  1090. // loop to the next to last char or to the last char if we need another digit to
  1091. // make a valid number (e.g. chars[0..5] = "1234E")
  1092. while (i < sz || (i < sz + 1 && allowSigns && !foundDigit)) {
  1093. if (chars[i] >= '0' && chars[i] <= '9') {
  1094. foundDigit = true;
  1095. allowSigns = false;
  1096. } else if (chars[i] == '.') {
  1097. if (hasDecPoint || hasExp) {
  1098. // two decimal points or dec in exponent
  1099. return false;
  1100. }
  1101. hasDecPoint = true;
  1102. } else if (chars[i] == 'e' || chars[i] == 'E') {
  1103. // we've already taken care of hex.
  1104. if (hasExp) {
  1105. // two E's
  1106. return false;
  1107. }
  1108. if (!foundDigit) {
  1109. return false;
  1110. }
  1111. hasExp = true;
  1112. allowSigns = true;
  1113. } else if (chars[i] == '+' || chars[i] == '-') {
  1114. if (!allowSigns) {
  1115. return false;
  1116. }
  1117. allowSigns = false;
  1118. foundDigit = false; // we need a digit after the E
  1119. } else {
  1120. return false;
  1121. }
  1122. i++;
  1123. }
  1124. if (i < chars.length) {
  1125. if (chars[i] >= '0' && chars[i] <= '9') {
  1126. // no type qualifier, OK
  1127. return true;
  1128. }
  1129. if (chars[i] == 'e' || chars[i] == 'E') {
  1130. // can't have an E at the last byte
  1131. return false;
  1132. }
  1133. if (!allowSigns
  1134. && (chars[i] == 'd'
  1135. || chars[i] == 'D'
  1136. || chars[i] == 'f'
  1137. || chars[i] == 'F')) {
  1138. return foundDigit;
  1139. }
  1140. if (chars[i] == 'l'
  1141. || chars[i] == 'L') {
  1142. // not allowing L with an exponoent
  1143. return foundDigit && !hasExp;
  1144. }
  1145. // last character is illegal
  1146. return false;
  1147. }
  1148. // allowSigns is true iff the val ends in 'E'
  1149. // found digit it to make sure weird stuff like '.' and '1E-' doesn't pass
  1150. return !allowSigns && foundDigit;
  1151. }
  1152. }