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 org.apache.commons.lang3.StringUtils; 024import org.apache.commons.lang3.SystemUtils; 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 minus one. */ 045 public static final Integer INTEGER_MINUS_ONE = Integer.valueOf(-1); 046 /** Reusable Short constant for zero. */ 047 public static final Short SHORT_ZERO = Short.valueOf((short) 0); 048 /** Reusable Short constant for one. */ 049 public static final Short SHORT_ONE = Short.valueOf((short) 1); 050 /** Reusable Short constant for minus one. */ 051 public static final Short SHORT_MINUS_ONE = Short.valueOf((short) -1); 052 /** Reusable Byte constant for zero. */ 053 public static final Byte BYTE_ZERO = Byte.valueOf((byte) 0); 054 /** Reusable Byte constant for one. */ 055 public static final Byte BYTE_ONE = Byte.valueOf((byte) 1); 056 /** Reusable Byte constant for minus one. */ 057 public static final Byte BYTE_MINUS_ONE = Byte.valueOf((byte) -1); 058 /** Reusable Double constant for zero. */ 059 public static final Double DOUBLE_ZERO = Double.valueOf(0.0d); 060 /** Reusable Double constant for one. */ 061 public static final Double DOUBLE_ONE = Double.valueOf(1.0d); 062 /** Reusable Double constant for minus one. */ 063 public static final Double DOUBLE_MINUS_ONE = Double.valueOf(-1.0d); 064 /** Reusable Float constant for zero. */ 065 public static final Float FLOAT_ZERO = Float.valueOf(0.0f); 066 /** Reusable Float constant for one. */ 067 public static final Float FLOAT_ONE = Float.valueOf(1.0f); 068 /** Reusable Float constant for minus one. */ 069 public static final Float FLOAT_MINUS_ONE = Float.valueOf(-1.0f); 070 071 /** 072 * <p><code>NumberUtils</code> instances should NOT be constructed in standard programming. 073 * Instead, the class should be used as <code>NumberUtils.toInt("6");</code>.</p> 074 * 075 * <p>This constructor is public to permit tools that require a JavaBean instance 076 * to operate.</p> 077 */ 078 public NumberUtils() { 079 super(); 080 } 081 082 //----------------------------------------------------------------------- 083 /** 084 * <p>Convert a <code>String</code> to an <code>int</code>, returning 085 * <code>zero</code> if the conversion fails.</p> 086 * 087 * <p>If the string is <code>null</code>, <code>zero</code> is returned.</p> 088 * 089 * <pre> 090 * NumberUtils.toInt(null) = 0 091 * NumberUtils.toInt("") = 0 092 * NumberUtils.toInt("1") = 1 093 * </pre> 094 * 095 * @param str the string to convert, may be null 096 * @return the int represented by the string, or <code>zero</code> if 097 * conversion fails 098 * @since 2.1 099 */ 100 public static int toInt(final String str) { 101 return toInt(str, 0); 102 } 103 104 /** 105 * <p>Convert a <code>String</code> to an <code>int</code>, returning a 106 * default value if the conversion fails.</p> 107 * 108 * <p>If the string is <code>null</code>, the default value is returned.</p> 109 * 110 * <pre> 111 * NumberUtils.toInt(null, 1) = 1 112 * NumberUtils.toInt("", 1) = 1 113 * NumberUtils.toInt("1", 0) = 1 114 * </pre> 115 * 116 * @param str the string to convert, may be null 117 * @param defaultValue the default value 118 * @return the int represented by the string, or the default if conversion fails 119 * @since 2.1 120 */ 121 public static int toInt(final String str, final int defaultValue) { 122 if(str == null) { 123 return defaultValue; 124 } 125 try { 126 return Integer.parseInt(str); 127 } catch (final NumberFormatException nfe) { 128 return defaultValue; 129 } 130 } 131 132 /** 133 * <p>Convert a <code>String</code> to a <code>long</code>, returning 134 * <code>zero</code> if the conversion fails.</p> 135 * 136 * <p>If the string is <code>null</code>, <code>zero</code> is returned.</p> 137 * 138 * <pre> 139 * NumberUtils.toLong(null) = 0L 140 * NumberUtils.toLong("") = 0L 141 * NumberUtils.toLong("1") = 1L 142 * </pre> 143 * 144 * @param str the string to convert, may be null 145 * @return the long represented by the string, or <code>0</code> if 146 * conversion fails 147 * @since 2.1 148 */ 149 public static long toLong(final String str) { 150 return toLong(str, 0L); 151 } 152 153 /** 154 * <p>Convert a <code>String</code> to a <code>long</code>, returning a 155 * default value if the conversion fails.</p> 156 * 157 * <p>If the string is <code>null</code>, the default value is returned.</p> 158 * 159 * <pre> 160 * NumberUtils.toLong(null, 1L) = 1L 161 * NumberUtils.toLong("", 1L) = 1L 162 * NumberUtils.toLong("1", 0L) = 1L 163 * </pre> 164 * 165 * @param str the string to convert, may be null 166 * @param defaultValue the default value 167 * @return the long represented by the string, or the default if conversion fails 168 * @since 2.1 169 */ 170 public static long toLong(final String str, final long defaultValue) { 171 if (str == null) { 172 return defaultValue; 173 } 174 try { 175 return Long.parseLong(str); 176 } catch (final NumberFormatException nfe) { 177 return defaultValue; 178 } 179 } 180 181 /** 182 * <p>Convert a <code>String</code> to a <code>float</code>, returning 183 * <code>0.0f</code> if the conversion fails.</p> 184 * 185 * <p>If the string <code>str</code> is <code>null</code>, 186 * <code>0.0f</code> is returned.</p> 187 * 188 * <pre> 189 * NumberUtils.toFloat(null) = 0.0f 190 * NumberUtils.toFloat("") = 0.0f 191 * NumberUtils.toFloat("1.5") = 1.5f 192 * </pre> 193 * 194 * @param str the string to convert, may be <code>null</code> 195 * @return the float represented by the string, or <code>0.0f</code> 196 * if conversion fails 197 * @since 2.1 198 */ 199 public static float toFloat(final String str) { 200 return toFloat(str, 0.0f); 201 } 202 203 /** 204 * <p>Convert a <code>String</code> to a <code>float</code>, returning a 205 * default value if the conversion fails.</p> 206 * 207 * <p>If the string <code>str</code> is <code>null</code>, the default 208 * value is returned.</p> 209 * 210 * <pre> 211 * NumberUtils.toFloat(null, 1.1f) = 1.0f 212 * NumberUtils.toFloat("", 1.1f) = 1.1f 213 * NumberUtils.toFloat("1.5", 0.0f) = 1.5f 214 * </pre> 215 * 216 * @param str the string to convert, may be <code>null</code> 217 * @param defaultValue the default value 218 * @return the float represented by the string, or defaultValue 219 * if conversion fails 220 * @since 2.1 221 */ 222 public static float toFloat(final String str, final float defaultValue) { 223 if (str == null) { 224 return defaultValue; 225 } 226 try { 227 return Float.parseFloat(str); 228 } catch (final NumberFormatException nfe) { 229 return defaultValue; 230 } 231 } 232 233 /** 234 * <p>Convert a <code>String</code> to a <code>double</code>, returning 235 * <code>0.0d</code> if the conversion fails.</p> 236 * 237 * <p>If the string <code>str</code> is <code>null</code>, 238 * <code>0.0d</code> is returned.</p> 239 * 240 * <pre> 241 * NumberUtils.toDouble(null) = 0.0d 242 * NumberUtils.toDouble("") = 0.0d 243 * NumberUtils.toDouble("1.5") = 1.5d 244 * </pre> 245 * 246 * @param str the string to convert, may be <code>null</code> 247 * @return the double represented by the string, or <code>0.0d</code> 248 * if conversion fails 249 * @since 2.1 250 */ 251 public static double toDouble(final String str) { 252 return toDouble(str, 0.0d); 253 } 254 255 /** 256 * <p>Convert a <code>String</code> to a <code>double</code>, returning a 257 * default value if the conversion fails.</p> 258 * 259 * <p>If the string <code>str</code> is <code>null</code>, the default 260 * value is returned.</p> 261 * 262 * <pre> 263 * NumberUtils.toDouble(null, 1.1d) = 1.1d 264 * NumberUtils.toDouble("", 1.1d) = 1.1d 265 * NumberUtils.toDouble("1.5", 0.0d) = 1.5d 266 * </pre> 267 * 268 * @param str the string to convert, may be <code>null</code> 269 * @param defaultValue the default value 270 * @return the double represented by the string, or defaultValue 271 * if conversion fails 272 * @since 2.1 273 */ 274 public static double toDouble(final String str, final double defaultValue) { 275 if (str == null) { 276 return defaultValue; 277 } 278 try { 279 return Double.parseDouble(str); 280 } catch (final NumberFormatException nfe) { 281 return defaultValue; 282 } 283 } 284 285 //----------------------------------------------------------------------- 286 /** 287 * <p>Convert a <code>String</code> to a <code>byte</code>, returning 288 * <code>zero</code> if the conversion fails.</p> 289 * 290 * <p>If the string is <code>null</code>, <code>zero</code> is returned.</p> 291 * 292 * <pre> 293 * NumberUtils.toByte(null) = 0 294 * NumberUtils.toByte("") = 0 295 * NumberUtils.toByte("1") = 1 296 * </pre> 297 * 298 * @param str the string to convert, may be null 299 * @return the byte represented by the string, or <code>zero</code> if 300 * conversion fails 301 * @since 2.5 302 */ 303 public static byte toByte(final String str) { 304 return toByte(str, (byte) 0); 305 } 306 307 /** 308 * <p>Convert a <code>String</code> to a <code>byte</code>, returning a 309 * default value if the conversion fails.</p> 310 * 311 * <p>If the string is <code>null</code>, the default value is returned.</p> 312 * 313 * <pre> 314 * NumberUtils.toByte(null, 1) = 1 315 * NumberUtils.toByte("", 1) = 1 316 * NumberUtils.toByte("1", 0) = 1 317 * </pre> 318 * 319 * @param str the string to convert, may be null 320 * @param defaultValue the default value 321 * @return the byte represented by the string, or the default if conversion fails 322 * @since 2.5 323 */ 324 public static byte toByte(final String str, final byte defaultValue) { 325 if(str == null) { 326 return defaultValue; 327 } 328 try { 329 return Byte.parseByte(str); 330 } catch (final NumberFormatException nfe) { 331 return defaultValue; 332 } 333 } 334 335 /** 336 * <p>Convert a <code>String</code> to a <code>short</code>, returning 337 * <code>zero</code> if the conversion fails.</p> 338 * 339 * <p>If the string is <code>null</code>, <code>zero</code> is returned.</p> 340 * 341 * <pre> 342 * NumberUtils.toShort(null) = 0 343 * NumberUtils.toShort("") = 0 344 * NumberUtils.toShort("1") = 1 345 * </pre> 346 * 347 * @param str the string to convert, may be null 348 * @return the short represented by the string, or <code>zero</code> if 349 * conversion fails 350 * @since 2.5 351 */ 352 public static short toShort(final String str) { 353 return toShort(str, (short) 0); 354 } 355 356 /** 357 * <p>Convert a <code>String</code> to an <code>short</code>, returning a 358 * default value if the conversion fails.</p> 359 * 360 * <p>If the string is <code>null</code>, the default value is returned.</p> 361 * 362 * <pre> 363 * NumberUtils.toShort(null, 1) = 1 364 * NumberUtils.toShort("", 1) = 1 365 * NumberUtils.toShort("1", 0) = 1 366 * </pre> 367 * 368 * @param str the string to convert, may be null 369 * @param defaultValue the default value 370 * @return the short represented by the string, or the default if conversion fails 371 * @since 2.5 372 */ 373 public static short toShort(final String str, final short defaultValue) { 374 if(str == null) { 375 return defaultValue; 376 } 377 try { 378 return Short.parseShort(str); 379 } catch (final NumberFormatException nfe) { 380 return defaultValue; 381 } 382 } 383 384 //----------------------------------------------------------------------- 385 // must handle Long, Float, Integer, Float, Short, 386 // BigDecimal, BigInteger and Byte 387 // useful methods: 388 // Byte.decode(String) 389 // Byte.valueOf(String,int radix) 390 // Byte.valueOf(String) 391 // Double.valueOf(String) 392 // Float.valueOf(String) 393 // Float.valueOf(String) 394 // Integer.valueOf(String,int radix) 395 // Integer.valueOf(String) 396 // Integer.decode(String) 397 // Integer.getInteger(String) 398 // Integer.getInteger(String,int val) 399 // Integer.getInteger(String,Integer val) 400 // Integer.valueOf(String) 401 // Double.valueOf(String) 402 // new Byte(String) 403 // Long.valueOf(String) 404 // Long.getLong(String) 405 // Long.getLong(String,int) 406 // Long.getLong(String,Integer) 407 // Long.valueOf(String,int) 408 // Long.valueOf(String) 409 // Short.valueOf(String) 410 // Short.decode(String) 411 // Short.valueOf(String,int) 412 // Short.valueOf(String) 413 // new BigDecimal(String) 414 // new BigInteger(String) 415 // new BigInteger(String,int radix) 416 // Possible inputs: 417 // 45 45.5 45E7 4.5E7 Hex Oct Binary xxxF xxxD xxxf xxxd 418 // plus minus everything. Prolly more. A lot are not separable. 419 420 /** 421 * <p>Turns a string value into a java.lang.Number.</p> 422 * 423 * <p>If the string starts with {@code 0x} or {@code -0x} (lower or upper case) or {@code #} or {@code -#}, it 424 * will be interpreted as a hexadecimal Integer - or Long, if the number of digits after the 425 * prefix is more than 8 - or BigInteger if there are more than 16 digits. 426 * </p> 427 * <p>Then, the value is examined for a type qualifier on the end, i.e. one of 428 * <code>'f','F','d','D','l','L'</code>. If it is found, it starts 429 * trying to create successively larger types from the type specified 430 * until one is found that can represent the value.</p> 431 * 432 * <p>If a type specifier is not found, it will check for a decimal point 433 * and then try successively larger types from <code>Integer</code> to 434 * <code>BigInteger</code> and from <code>Float</code> to 435 * <code>BigDecimal</code>.</p> 436 * 437 * <p> 438 * Integral values with a leading {@code 0} will be interpreted as octal; the returned number will 439 * be Integer, Long or BigDecimal as appropriate. 440 * </p> 441 * 442 * <p>Returns <code>null</code> if the string is <code>null</code>.</p> 443 * 444 * <p>This method does not trim the input string, i.e., strings with leading 445 * or trailing spaces will generate NumberFormatExceptions.</p> 446 * 447 * @param str String containing a number, may be null 448 * @return Number created from the string (or null if the input is null) 449 * @throws NumberFormatException if the value cannot be converted 450 */ 451 public static Number createNumber(final String str) throws NumberFormatException { 452 if (str == null) { 453 return null; 454 } 455 if (StringUtils.isBlank(str)) { 456 throw new NumberFormatException("A blank string is not a valid number"); 457 } 458 // Need to deal with all possible hex prefixes here 459 final String[] hex_prefixes = {"0x", "0X", "-0x", "-0X", "#", "-#"}; 460 int pfxLen = 0; 461 for(final String pfx : hex_prefixes) { 462 if (str.startsWith(pfx)) { 463 pfxLen += pfx.length(); 464 break; 465 } 466 } 467 if (pfxLen > 0) { // we have a hex number 468 char firstSigDigit = 0; // strip leading zeroes 469 for(int i = pfxLen; i < str.length(); i++) { 470 firstSigDigit = str.charAt(i); 471 if (firstSigDigit == '0') { // count leading zeroes 472 pfxLen++; 473 } else { 474 break; 475 } 476 } 477 final int hexDigits = str.length() - pfxLen; 478 if (hexDigits > 16 || hexDigits == 16 && firstSigDigit > '7') { // too many for Long 479 return createBigInteger(str); 480 } 481 if (hexDigits > 8 || hexDigits == 8 && firstSigDigit > '7') { // too many for an int 482 return createLong(str); 483 } 484 return createInteger(str); 485 } 486 final char lastChar = str.charAt(str.length() - 1); 487 String mant; 488 String dec; 489 String exp; 490 final int decPos = str.indexOf('.'); 491 final int expPos = str.indexOf('e') + str.indexOf('E') + 1; // assumes both not present 492 // if both e and E are present, this is caught by the checks on expPos (which prevent IOOBE) 493 // and the parsing which will detect if e or E appear in a number due to using the wrong offset 494 495 if (decPos > -1) { // there is a decimal point 496 if (expPos > -1) { // there is an exponent 497 if (expPos < decPos || expPos > str.length()) { // prevents double exponent causing IOOBE 498 throw new NumberFormatException(str + " is not a valid number."); 499 } 500 dec = str.substring(decPos + 1, expPos); 501 } else { 502 dec = str.substring(decPos + 1); 503 } 504 mant = getMantissa(str, decPos); 505 } else { 506 if (expPos > -1) { 507 if (expPos > str.length()) { // prevents double exponent causing IOOBE 508 throw new NumberFormatException(str + " is not a valid number."); 509 } 510 mant = getMantissa(str, expPos); 511 } else { 512 mant = getMantissa(str); 513 } 514 dec = null; 515 } 516 if (!Character.isDigit(lastChar) && lastChar != '.') { 517 if (expPos > -1 && expPos < str.length() - 1) { 518 exp = str.substring(expPos + 1, str.length() - 1); 519 } else { 520 exp = null; 521 } 522 //Requesting a specific type.. 523 final String numeric = str.substring(0, str.length() - 1); 524 final boolean allZeros = isAllZeros(mant) && isAllZeros(exp); 525 switch (lastChar) { 526 case 'l' : 527 case 'L' : 528 if (dec == null 529 && exp == null 530 && (numeric.charAt(0) == '-' && isDigits(numeric.substring(1)) || isDigits(numeric))) { 531 try { 532 return createLong(numeric); 533 } catch (final NumberFormatException nfe) { // NOPMD 534 // Too big for a long 535 } 536 return createBigInteger(numeric); 537 538 } 539 throw new NumberFormatException(str + " is not a valid number."); 540 case 'f' : 541 case 'F' : 542 try { 543 final Float f = NumberUtils.createFloat(str); 544 if (!(f.isInfinite() || f.floatValue() == 0.0F && !allZeros)) { 545 //If it's too big for a float or the float value = 0 and the string 546 //has non-zeros in it, then float does not have the precision we want 547 return f; 548 } 549 550 } catch (final NumberFormatException nfe) { // NOPMD 551 // ignore the bad number 552 } 553 //$FALL-THROUGH$ 554 case 'd' : 555 case 'D' : 556 try { 557 final Double d = NumberUtils.createDouble(str); 558 if (!(d.isInfinite() || d.floatValue() == 0.0D && !allZeros)) { 559 return d; 560 } 561 } catch (final NumberFormatException nfe) { // NOPMD 562 // ignore the bad number 563 } 564 try { 565 return createBigDecimal(numeric); 566 } catch (final NumberFormatException e) { // NOPMD 567 // ignore the bad number 568 } 569 //$FALL-THROUGH$ 570 default : 571 throw new NumberFormatException(str + " is not a valid number."); 572 573 } 574 } 575 //User doesn't have a preference on the return type, so let's start 576 //small and go from there... 577 if (expPos > -1 && expPos < str.length() - 1) { 578 exp = str.substring(expPos + 1, str.length()); 579 } else { 580 exp = null; 581 } 582 if (dec == null && exp == null) { // no decimal point and no exponent 583 //Must be an Integer, Long, Biginteger 584 try { 585 return createInteger(str); 586 } catch (final NumberFormatException nfe) { // NOPMD 587 // ignore the bad number 588 } 589 try { 590 return createLong(str); 591 } catch (final NumberFormatException nfe) { // NOPMD 592 // ignore the bad number 593 } 594 return createBigInteger(str); 595 } 596 597 //Must be a Float, Double, BigDecimal 598 final boolean allZeros = isAllZeros(mant) && isAllZeros(exp); 599 try { 600 final Float f = createFloat(str); 601 final Double d = createDouble(str); 602 if (!f.isInfinite() 603 && !(f.floatValue() == 0.0F && !allZeros) 604 && f.toString().equals(d.toString())) { 605 return f; 606 } 607 if (!d.isInfinite() && !(d.doubleValue() == 0.0D && !allZeros)) { 608 final BigDecimal b = createBigDecimal(str); 609 if (b.compareTo(BigDecimal.valueOf(d)) == 0) { 610 return d; 611 } 612 return b; 613 } 614 } catch (final NumberFormatException nfe) { // NOPMD 615 // ignore the bad number 616 } 617 return createBigDecimal(str); 618 } 619 620 /** 621 * <p>Utility method for {@link #createNumber(java.lang.String)}.</p> 622 * 623 * <p>Returns mantissa of the given number.</p> 624 * 625 * @param str the string representation of the number 626 * @return mantissa of the given number 627 */ 628 private static String getMantissa(final String str) { 629 return getMantissa(str, str.length()); 630 } 631 632 /** 633 * <p>Utility method for {@link #createNumber(java.lang.String)}.</p> 634 * 635 * <p>Returns mantissa of the given number.</p> 636 * 637 * @param str the string representation of the number 638 * @param stopPos the position of the exponent or decimal point 639 * @return mantissa of the given number 640 */ 641 private static String getMantissa(final String str, final int stopPos) { 642 final char firstChar = str.charAt(0); 643 final boolean hasSign = firstChar == '-' || firstChar == '+'; 644 645 return hasSign ? str.substring(1, stopPos) : str.substring(0, stopPos); 646 } 647 648 /** 649 * <p>Utility method for {@link #createNumber(java.lang.String)}.</p> 650 * 651 * <p>Returns <code>true</code> if s is <code>null</code>.</p> 652 * 653 * @param str the String to check 654 * @return if it is all zeros or <code>null</code> 655 */ 656 private static boolean isAllZeros(final String str) { 657 if (str == null) { 658 return true; 659 } 660 for (int i = str.length() - 1; i >= 0; i--) { 661 if (str.charAt(i) != '0') { 662 return false; 663 } 664 } 665 return str.length() > 0; 666 } 667 668 //----------------------------------------------------------------------- 669 /** 670 * <p>Convert a <code>String</code> to a <code>Float</code>.</p> 671 * 672 * <p>Returns <code>null</code> if the string is <code>null</code>.</p> 673 * 674 * @param str a <code>String</code> to convert, may be null 675 * @return converted <code>Float</code> (or null if the input is null) 676 * @throws NumberFormatException if the value cannot be converted 677 */ 678 public static Float createFloat(final String str) { 679 if (str == null) { 680 return null; 681 } 682 return Float.valueOf(str); 683 } 684 685 /** 686 * <p>Convert a <code>String</code> to a <code>Double</code>.</p> 687 * 688 * <p>Returns <code>null</code> if the string is <code>null</code>.</p> 689 * 690 * @param str a <code>String</code> to convert, may be null 691 * @return converted <code>Double</code> (or null if the input is null) 692 * @throws NumberFormatException if the value cannot be converted 693 */ 694 public static Double createDouble(final String str) { 695 if (str == null) { 696 return null; 697 } 698 return Double.valueOf(str); 699 } 700 701 /** 702 * <p>Convert a <code>String</code> to a <code>Integer</code>, handling 703 * hex (0xhhhh) and octal (0dddd) notations. 704 * N.B. a leading zero means octal; spaces are not trimmed.</p> 705 * 706 * <p>Returns <code>null</code> if the string is <code>null</code>.</p> 707 * 708 * @param str a <code>String</code> to convert, may be null 709 * @return converted <code>Integer</code> (or null if the input is null) 710 * @throws NumberFormatException if the value cannot be converted 711 */ 712 public static Integer createInteger(final String str) { 713 if (str == null) { 714 return null; 715 } 716 // decode() handles 0xAABD and 0777 (hex and octal) as well. 717 return Integer.decode(str); 718 } 719 720 /** 721 * <p>Convert a <code>String</code> to a <code>Long</code>; 722 * since 3.1 it handles hex (0Xhhhh) and octal (0ddd) notations. 723 * N.B. a leading zero means octal; spaces are not trimmed.</p> 724 * 725 * <p>Returns <code>null</code> if the string is <code>null</code>.</p> 726 * 727 * @param str a <code>String</code> to convert, may be null 728 * @return converted <code>Long</code> (or null if the input is null) 729 * @throws NumberFormatException if the value cannot be converted 730 */ 731 public static Long createLong(final String str) { 732 if (str == null) { 733 return null; 734 } 735 return Long.decode(str); 736 } 737 738 /** 739 * <p>Convert a <code>String</code> to a <code>BigInteger</code>; 740 * since 3.2 it handles hex (0x or #) and octal (0) notations.</p> 741 * 742 * <p>Returns <code>null</code> if the string is <code>null</code>.</p> 743 * 744 * @param str a <code>String</code> to convert, may be null 745 * @return converted <code>BigInteger</code> (or null if the input is null) 746 * @throws NumberFormatException if the value cannot be converted 747 */ 748 public static BigInteger createBigInteger(final String str) { 749 if (str == null) { 750 return null; 751 } 752 int pos = 0; // offset within string 753 int radix = 10; 754 boolean negate = false; // need to negate later? 755 if (str.startsWith("-")) { 756 negate = true; 757 pos = 1; 758 } 759 if (str.startsWith("0x", pos) || str.startsWith("0X", pos)) { // hex 760 radix = 16; 761 pos += 2; 762 } else if (str.startsWith("#", pos)) { // alternative hex (allowed by Long/Integer) 763 radix = 16; 764 pos ++; 765 } else if (str.startsWith("0", pos) && str.length() > pos + 1) { // octal; so long as there are additional digits 766 radix = 8; 767 pos ++; 768 } // default is to treat as decimal 769 770 final BigInteger value = new BigInteger(str.substring(pos), radix); 771 return negate ? value.negate() : value; 772 } 773 774 /** 775 * <p>Convert a <code>String</code> to a <code>BigDecimal</code>.</p> 776 * 777 * <p>Returns <code>null</code> if the string is <code>null</code>.</p> 778 * 779 * @param str a <code>String</code> to convert, may be null 780 * @return converted <code>BigDecimal</code> (or null if the input is null) 781 * @throws NumberFormatException if the value cannot be converted 782 */ 783 public static BigDecimal createBigDecimal(final String str) { 784 if (str == null) { 785 return null; 786 } 787 // handle JDK1.3.1 bug where "" throws IndexOutOfBoundsException 788 if (StringUtils.isBlank(str)) { 789 throw new NumberFormatException("A blank string is not a valid number"); 790 } 791 if (str.trim().startsWith("--")) { 792 // this is protection for poorness in java.lang.BigDecimal. 793 // it accepts this as a legal value, but it does not appear 794 // to be in specification of class. OS X Java parses it to 795 // a wrong value. 796 throw new NumberFormatException(str + " is not a valid number."); 797 } 798 return new BigDecimal(str); 799 } 800 801 // Min in array 802 //-------------------------------------------------------------------- 803 /** 804 * <p>Returns the minimum value in an array.</p> 805 * 806 * @param array an array, must not be null or empty 807 * @return the minimum value in the array 808 * @throws IllegalArgumentException if <code>array</code> is <code>null</code> 809 * @throws IllegalArgumentException if <code>array</code> is empty 810 * @since 3.4 Changed signature from min(long[]) to min(long...) 811 */ 812 public static long min(final long... array) { 813 // Validates input 814 validateArray(array); 815 816 // Finds and returns min 817 long min = array[0]; 818 for (int i = 1; i < array.length; i++) { 819 if (array[i] < min) { 820 min = array[i]; 821 } 822 } 823 824 return min; 825 } 826 827 /** 828 * <p>Returns the minimum value in an array.</p> 829 * 830 * @param array an array, must not be null or empty 831 * @return the minimum value in the array 832 * @throws IllegalArgumentException if <code>array</code> is <code>null</code> 833 * @throws IllegalArgumentException if <code>array</code> is empty 834 * @since 3.4 Changed signature from min(int[]) to min(int...) 835 */ 836 public static int min(final int... array) { 837 // Validates input 838 validateArray(array); 839 840 // Finds and returns min 841 int min = array[0]; 842 for (int j = 1; j < array.length; j++) { 843 if (array[j] < min) { 844 min = array[j]; 845 } 846 } 847 848 return min; 849 } 850 851 /** 852 * <p>Returns the minimum value in an array.</p> 853 * 854 * @param array an array, must not be null or empty 855 * @return the minimum value in the array 856 * @throws IllegalArgumentException if <code>array</code> is <code>null</code> 857 * @throws IllegalArgumentException if <code>array</code> is empty 858 * @since 3.4 Changed signature from min(short[]) to min(short...) 859 */ 860 public static short min(final short... array) { 861 // Validates input 862 validateArray(array); 863 864 // Finds and returns min 865 short min = array[0]; 866 for (int i = 1; i < array.length; i++) { 867 if (array[i] < min) { 868 min = array[i]; 869 } 870 } 871 872 return min; 873 } 874 875 /** 876 * <p>Returns the minimum value in an array.</p> 877 * 878 * @param array an array, must not be null or empty 879 * @return the minimum value in the array 880 * @throws IllegalArgumentException if <code>array</code> is <code>null</code> 881 * @throws IllegalArgumentException if <code>array</code> is empty 882 * @since 3.4 Changed signature from min(byte[]) to min(byte...) 883 */ 884 public static byte min(final byte... array) { 885 // Validates input 886 validateArray(array); 887 888 // Finds and returns min 889 byte min = array[0]; 890 for (int i = 1; i < array.length; i++) { 891 if (array[i] < min) { 892 min = array[i]; 893 } 894 } 895 896 return min; 897 } 898 899 /** 900 * <p>Returns the minimum value in an array.</p> 901 * 902 * @param array an array, must not be null or empty 903 * @return the minimum value in the array 904 * @throws IllegalArgumentException if <code>array</code> is <code>null</code> 905 * @throws IllegalArgumentException if <code>array</code> is empty 906 * @see IEEE754rUtils#min(double[]) IEEE754rUtils for a version of this method that handles NaN differently 907 * @since 3.4 Changed signature from min(double[]) to min(double...) 908 */ 909 public static double min(final double... array) { 910 // Validates input 911 validateArray(array); 912 913 // Finds and returns min 914 double min = array[0]; 915 for (int i = 1; i < array.length; i++) { 916 if (Double.isNaN(array[i])) { 917 return Double.NaN; 918 } 919 if (array[i] < min) { 920 min = array[i]; 921 } 922 } 923 924 return min; 925 } 926 927 /** 928 * <p>Returns the minimum value in an array.</p> 929 * 930 * @param array an array, must not be null or empty 931 * @return the minimum value in the array 932 * @throws IllegalArgumentException if <code>array</code> is <code>null</code> 933 * @throws IllegalArgumentException if <code>array</code> is empty 934 * @see IEEE754rUtils#min(float[]) IEEE754rUtils for a version of this method that handles NaN differently 935 * @since 3.4 Changed signature from min(float[]) to min(float...) 936 */ 937 public static float min(final float... array) { 938 // Validates input 939 validateArray(array); 940 941 // Finds and returns min 942 float min = array[0]; 943 for (int i = 1; i < array.length; i++) { 944 if (Float.isNaN(array[i])) { 945 return Float.NaN; 946 } 947 if (array[i] < min) { 948 min = array[i]; 949 } 950 } 951 952 return min; 953 } 954 955 // Max in array 956 //-------------------------------------------------------------------- 957 /** 958 * <p>Returns the maximum value in an array.</p> 959 * 960 * @param array an array, must not be null or empty 961 * @return the maximum value in the array 962 * @throws IllegalArgumentException if <code>array</code> is <code>null</code> 963 * @throws IllegalArgumentException if <code>array</code> is empty 964 * @since 3.4 Changed signature from max(long[]) to max(long...) 965 */ 966 public static long max(final long... array) { 967 // Validates input 968 validateArray(array); 969 970 // Finds and returns max 971 long max = array[0]; 972 for (int j = 1; j < array.length; j++) { 973 if (array[j] > max) { 974 max = array[j]; 975 } 976 } 977 978 return max; 979 } 980 981 /** 982 * <p>Returns the maximum value in an array.</p> 983 * 984 * @param array an array, must not be null or empty 985 * @return the maximum value in the array 986 * @throws IllegalArgumentException if <code>array</code> is <code>null</code> 987 * @throws IllegalArgumentException if <code>array</code> is empty 988 * @since 3.4 Changed signature from max(int[]) to max(int...) 989 */ 990 public static int max(final int... array) { 991 // Validates input 992 validateArray(array); 993 994 // Finds and returns max 995 int max = array[0]; 996 for (int j = 1; j < array.length; j++) { 997 if (array[j] > max) { 998 max = array[j]; 999 } 1000 } 1001 1002 return max; 1003 } 1004 1005 /** 1006 * <p>Returns the maximum value in an array.</p> 1007 * 1008 * @param array an array, must not be null or empty 1009 * @return the maximum value in the array 1010 * @throws IllegalArgumentException if <code>array</code> is <code>null</code> 1011 * @throws IllegalArgumentException if <code>array</code> is empty 1012 * @since 3.4 Changed signature from max(short[]) to max(short...) 1013 */ 1014 public static short max(final short... array) { 1015 // Validates input 1016 validateArray(array); 1017 1018 // Finds and returns max 1019 short max = array[0]; 1020 for (int i = 1; i < array.length; i++) { 1021 if (array[i] > max) { 1022 max = array[i]; 1023 } 1024 } 1025 1026 return max; 1027 } 1028 1029 /** 1030 * <p>Returns the maximum value in an array.</p> 1031 * 1032 * @param array an array, must not be null or empty 1033 * @return the maximum value in the array 1034 * @throws IllegalArgumentException if <code>array</code> is <code>null</code> 1035 * @throws IllegalArgumentException if <code>array</code> is empty 1036 * @since 3.4 Changed signature from max(byte[]) to max(byte...) 1037 */ 1038 public static byte max(final byte... array) { 1039 // Validates input 1040 validateArray(array); 1041 1042 // Finds and returns max 1043 byte max = array[0]; 1044 for (int i = 1; i < array.length; i++) { 1045 if (array[i] > max) { 1046 max = array[i]; 1047 } 1048 } 1049 1050 return max; 1051 } 1052 1053 /** 1054 * <p>Returns the maximum value in an array.</p> 1055 * 1056 * @param array an array, must not be null or empty 1057 * @return the maximum value in the array 1058 * @throws IllegalArgumentException if <code>array</code> is <code>null</code> 1059 * @throws IllegalArgumentException if <code>array</code> is empty 1060 * @see IEEE754rUtils#max(double[]) IEEE754rUtils for a version of this method that handles NaN differently 1061 * @since 3.4 Changed signature from max(double[]) to max(double...) 1062 */ 1063 public static double max(final double... array) { 1064 // Validates input 1065 validateArray(array); 1066 1067 // Finds and returns max 1068 double max = array[0]; 1069 for (int j = 1; j < array.length; j++) { 1070 if (Double.isNaN(array[j])) { 1071 return Double.NaN; 1072 } 1073 if (array[j] > max) { 1074 max = array[j]; 1075 } 1076 } 1077 1078 return max; 1079 } 1080 1081 /** 1082 * <p>Returns the maximum value in an array.</p> 1083 * 1084 * @param array an array, must not be null or empty 1085 * @return the maximum value in the array 1086 * @throws IllegalArgumentException if <code>array</code> is <code>null</code> 1087 * @throws IllegalArgumentException if <code>array</code> is empty 1088 * @see IEEE754rUtils#max(float[]) IEEE754rUtils for a version of this method that handles NaN differently 1089 * @since 3.4 Changed signature from max(float[]) to max(float...) 1090 */ 1091 public static float max(final float... array) { 1092 // Validates input 1093 validateArray(array); 1094 1095 // Finds and returns max 1096 float max = array[0]; 1097 for (int j = 1; j < array.length; j++) { 1098 if (Float.isNaN(array[j])) { 1099 return Float.NaN; 1100 } 1101 if (array[j] > max) { 1102 max = array[j]; 1103 } 1104 } 1105 1106 return max; 1107 } 1108 1109 /** 1110 * Checks if the specified array is neither null nor empty. 1111 * 1112 * @param array the array to check 1113 * @throws IllegalArgumentException if {@code array} is either {@code null} or empty 1114 */ 1115 private static void validateArray(final Object array) { 1116 if (array == null) { 1117 throw new IllegalArgumentException("The Array must not be null"); 1118 } 1119 Validate.isTrue(Array.getLength(array) != 0, "Array cannot be empty."); 1120 } 1121 1122 // 3 param min 1123 //----------------------------------------------------------------------- 1124 /** 1125 * <p>Gets the minimum of three <code>long</code> values.</p> 1126 * 1127 * @param a value 1 1128 * @param b value 2 1129 * @param c value 3 1130 * @return the smallest of the values 1131 */ 1132 public static long min(long a, final long b, final long c) { 1133 if (b < a) { 1134 a = b; 1135 } 1136 if (c < a) { 1137 a = c; 1138 } 1139 return a; 1140 } 1141 1142 /** 1143 * <p>Gets the minimum of three <code>int</code> values.</p> 1144 * 1145 * @param a value 1 1146 * @param b value 2 1147 * @param c value 3 1148 * @return the smallest of the values 1149 */ 1150 public static int min(int a, final int b, final int c) { 1151 if (b < a) { 1152 a = b; 1153 } 1154 if (c < a) { 1155 a = c; 1156 } 1157 return a; 1158 } 1159 1160 /** 1161 * <p>Gets the minimum of three <code>short</code> values.</p> 1162 * 1163 * @param a value 1 1164 * @param b value 2 1165 * @param c value 3 1166 * @return the smallest of the values 1167 */ 1168 public static short min(short a, final short b, final short c) { 1169 if (b < a) { 1170 a = b; 1171 } 1172 if (c < a) { 1173 a = c; 1174 } 1175 return a; 1176 } 1177 1178 /** 1179 * <p>Gets the minimum of three <code>byte</code> values.</p> 1180 * 1181 * @param a value 1 1182 * @param b value 2 1183 * @param c value 3 1184 * @return the smallest of the values 1185 */ 1186 public static byte min(byte a, final byte b, final byte c) { 1187 if (b < a) { 1188 a = b; 1189 } 1190 if (c < a) { 1191 a = c; 1192 } 1193 return a; 1194 } 1195 1196 /** 1197 * <p>Gets the minimum of three <code>double</code> values.</p> 1198 * 1199 * <p>If any value is <code>NaN</code>, <code>NaN</code> is 1200 * returned. Infinity is handled.</p> 1201 * 1202 * @param a value 1 1203 * @param b value 2 1204 * @param c value 3 1205 * @return the smallest of the values 1206 * @see IEEE754rUtils#min(double, double, double) for a version of this method that handles NaN differently 1207 */ 1208 public static double min(final double a, final double b, final double c) { 1209 return Math.min(Math.min(a, b), c); 1210 } 1211 1212 /** 1213 * <p>Gets the minimum of three <code>float</code> values.</p> 1214 * 1215 * <p>If any value is <code>NaN</code>, <code>NaN</code> is 1216 * returned. Infinity is handled.</p> 1217 * 1218 * @param a value 1 1219 * @param b value 2 1220 * @param c value 3 1221 * @return the smallest of the values 1222 * @see IEEE754rUtils#min(float, float, float) for a version of this method that handles NaN differently 1223 */ 1224 public static float min(final float a, final float b, final float c) { 1225 return Math.min(Math.min(a, b), c); 1226 } 1227 1228 // 3 param max 1229 //----------------------------------------------------------------------- 1230 /** 1231 * <p>Gets the maximum of three <code>long</code> values.</p> 1232 * 1233 * @param a value 1 1234 * @param b value 2 1235 * @param c value 3 1236 * @return the largest of the values 1237 */ 1238 public static long max(long a, final long b, final long c) { 1239 if (b > a) { 1240 a = b; 1241 } 1242 if (c > a) { 1243 a = c; 1244 } 1245 return a; 1246 } 1247 1248 /** 1249 * <p>Gets the maximum of three <code>int</code> values.</p> 1250 * 1251 * @param a value 1 1252 * @param b value 2 1253 * @param c value 3 1254 * @return the largest of the values 1255 */ 1256 public static int max(int a, final int b, final int c) { 1257 if (b > a) { 1258 a = b; 1259 } 1260 if (c > a) { 1261 a = c; 1262 } 1263 return a; 1264 } 1265 1266 /** 1267 * <p>Gets the maximum of three <code>short</code> values.</p> 1268 * 1269 * @param a value 1 1270 * @param b value 2 1271 * @param c value 3 1272 * @return the largest of the values 1273 */ 1274 public static short max(short a, final short b, final short c) { 1275 if (b > a) { 1276 a = b; 1277 } 1278 if (c > a) { 1279 a = c; 1280 } 1281 return a; 1282 } 1283 1284 /** 1285 * <p>Gets the maximum of three <code>byte</code> values.</p> 1286 * 1287 * @param a value 1 1288 * @param b value 2 1289 * @param c value 3 1290 * @return the largest of the values 1291 */ 1292 public static byte max(byte a, final byte b, final byte c) { 1293 if (b > a) { 1294 a = b; 1295 } 1296 if (c > a) { 1297 a = c; 1298 } 1299 return a; 1300 } 1301 1302 /** 1303 * <p>Gets the maximum of three <code>double</code> values.</p> 1304 * 1305 * <p>If any value is <code>NaN</code>, <code>NaN</code> is 1306 * returned. Infinity is handled.</p> 1307 * 1308 * @param a value 1 1309 * @param b value 2 1310 * @param c value 3 1311 * @return the largest of the values 1312 * @see IEEE754rUtils#max(double, double, double) for a version of this method that handles NaN differently 1313 */ 1314 public static double max(final double a, final double b, final double c) { 1315 return Math.max(Math.max(a, b), c); 1316 } 1317 1318 /** 1319 * <p>Gets the maximum of three <code>float</code> values.</p> 1320 * 1321 * <p>If any value is <code>NaN</code>, <code>NaN</code> is 1322 * returned. Infinity is handled.</p> 1323 * 1324 * @param a value 1 1325 * @param b value 2 1326 * @param c value 3 1327 * @return the largest of the values 1328 * @see IEEE754rUtils#max(float, float, float) for a version of this method that handles NaN differently 1329 */ 1330 public static float max(final float a, final float b, final float c) { 1331 return Math.max(Math.max(a, b), c); 1332 } 1333 1334 //----------------------------------------------------------------------- 1335 /** 1336 * <p>Checks whether the <code>String</code> contains only 1337 * digit characters.</p> 1338 * 1339 * <p><code>Null</code> and empty String will return 1340 * <code>false</code>.</p> 1341 * 1342 * @param str the <code>String</code> to check 1343 * @return <code>true</code> if str contains only Unicode numeric 1344 */ 1345 public static boolean isDigits(final String str) { 1346 return StringUtils.isNumeric(str); 1347 } 1348 1349 /** 1350 * <p>Checks whether the String a valid Java number.</p> 1351 * 1352 * <p>Valid numbers include hexadecimal marked with the <code>0x</code> or 1353 * <code>0X</code> qualifier, octal numbers, scientific notation and 1354 * numbers marked with a type qualifier (e.g. 123L).</p> 1355 * 1356 * <p>Non-hexadecimal strings beginning with a leading zero are 1357 * treated as octal values. Thus the string <code>09</code> will return 1358 * <code>false</code>, since <code>9</code> is not a valid octal value. 1359 * However, numbers beginning with {@code 0.} are treated as decimal.</p> 1360 * 1361 * <p><code>null</code> and empty/blank {@code String} will return 1362 * <code>false</code>.</p> 1363 * 1364 * <p>Note, {@link #createNumber(String)} should return a number for every 1365 * input resuling in <code>true</code>.</p> 1366 * 1367 * @param str the <code>String</code> to check 1368 * @return <code>true</code> if the string is a correctly formatted number 1369 * @since 3.3 the code supports hex {@code 0Xhhh} an 1370 * octal {@code 0ddd} validation 1371 * @deprecated This feature will be removed in Lang 4.0, 1372 * use {@link NumberUtils#isCreatable(String)} instead 1373 */ 1374 @Deprecated 1375 public static boolean isNumber(final String str) { 1376 return isCreatable(str); 1377 } 1378 1379 /** 1380 * <p>Checks whether the String a valid Java number.</p> 1381 * 1382 * <p>Valid numbers include hexadecimal marked with the <code>0x</code> or 1383 * <code>0X</code> qualifier, octal numbers, scientific notation and 1384 * numbers marked with a type qualifier (e.g. 123L).</p> 1385 * 1386 * <p>Non-hexadecimal strings beginning with a leading zero are 1387 * treated as octal values. Thus the string <code>09</code> will return 1388 * <code>false</code>, since <code>9</code> is not a valid octal value. 1389 * However, numbers beginning with {@code 0.} are treated as decimal.</p> 1390 * 1391 * <p><code>null</code> and empty/blank {@code String} will return 1392 * <code>false</code>.</p> 1393 * 1394 * <p>Note, {@link #createNumber(String)} should return a number for every 1395 * input resuling in <code>true</code>.</p> 1396 * 1397 * @param str the <code>String</code> to check 1398 * @return <code>true</code> if the string is a correctly formatted number 1399 * @since 3.5 the code supports the "+" suffix on numbers except for integers in Java 1.6 1400 */ 1401 public static boolean isCreatable(final String str) { 1402 if (StringUtils.isEmpty(str)) { 1403 return false; 1404 } 1405 final char[] chars = str.toCharArray(); 1406 int sz = chars.length; 1407 boolean hasExp = false; 1408 boolean hasDecPoint = false; 1409 boolean allowSigns = false; 1410 boolean foundDigit = false; 1411 // deal with any possible sign up front 1412 final int start = chars[0] == '-' || chars[0] == '+' ? 1 : 0; 1413 final boolean hasLeadingPlusSign = start == 1 && chars[0] == '+'; 1414 if (sz > start + 1 && chars[start] == '0') { // leading 0 1415 if (chars[start + 1] == 'x' || chars[start + 1] == 'X') { // leading 0x/0X 1416 int i = start + 2; 1417 if (i == sz) { 1418 return false; // str == "0x" 1419 } 1420 // checking hex (it can't be anything else) 1421 for (; i < chars.length; i++) { 1422 if ((chars[i] < '0' || chars[i] > '9') 1423 && (chars[i] < 'a' || chars[i] > 'f') 1424 && (chars[i] < 'A' || chars[i] > 'F')) { 1425 return false; 1426 } 1427 } 1428 return true; 1429 } else if (Character.isDigit(chars[start + 1])) { 1430 // leading 0, but not hex, must be octal 1431 int i = start + 1; 1432 for (; i < chars.length; i++) { 1433 if (chars[i] < '0' || chars[i] > '7') { 1434 return false; 1435 } 1436 } 1437 return true; 1438 } 1439 } 1440 sz--; // don't want to loop to the last char, check it afterwords 1441 // for type qualifiers 1442 int i = start; 1443 // loop to the next to last char or to the last char if we need another digit to 1444 // make a valid number (e.g. chars[0..5] = "1234E") 1445 while (i < sz || i < sz + 1 && allowSigns && !foundDigit) { 1446 if (chars[i] >= '0' && chars[i] <= '9') { 1447 foundDigit = true; 1448 allowSigns = false; 1449 1450 } else if (chars[i] == '.') { 1451 if (hasDecPoint || hasExp) { 1452 // two decimal points or dec in exponent 1453 return false; 1454 } 1455 hasDecPoint = true; 1456 } else if (chars[i] == 'e' || chars[i] == 'E') { 1457 // we've already taken care of hex. 1458 if (hasExp) { 1459 // two E's 1460 return false; 1461 } 1462 if (!foundDigit) { 1463 return false; 1464 } 1465 hasExp = true; 1466 allowSigns = true; 1467 } else if (chars[i] == '+' || chars[i] == '-') { 1468 if (!allowSigns) { 1469 return false; 1470 } 1471 allowSigns = false; 1472 foundDigit = false; // we need a digit after the E 1473 } else { 1474 return false; 1475 } 1476 i++; 1477 } 1478 if (i < chars.length) { 1479 if (chars[i] >= '0' && chars[i] <= '9') { 1480 if (SystemUtils.IS_JAVA_1_6 && hasLeadingPlusSign && !hasDecPoint) { 1481 return false; 1482 } 1483 // no type qualifier, OK 1484 return true; 1485 } 1486 if (chars[i] == 'e' || chars[i] == 'E') { 1487 // can't have an E at the last byte 1488 return false; 1489 } 1490 if (chars[i] == '.') { 1491 if (hasDecPoint || hasExp) { 1492 // two decimal points or dec in exponent 1493 return false; 1494 } 1495 // single trailing decimal point after non-exponent is ok 1496 return foundDigit; 1497 } 1498 if (!allowSigns 1499 && (chars[i] == 'd' 1500 || chars[i] == 'D' 1501 || chars[i] == 'f' 1502 || chars[i] == 'F')) { 1503 return foundDigit; 1504 } 1505 if (chars[i] == 'l' 1506 || chars[i] == 'L') { 1507 // not allowing L with an exponent or decimal point 1508 return foundDigit && !hasExp && !hasDecPoint; 1509 } 1510 // last character is illegal 1511 return false; 1512 } 1513 // allowSigns is true iff the val ends in 'E' 1514 // found digit it to make sure weird stuff like '.' and '1E-' doesn't pass 1515 return !allowSigns && foundDigit; 1516 } 1517 1518 /** 1519 * <p>Checks whether the given String is a parsable number.</p> 1520 * 1521 * <p>Parsable numbers include those Strings understood by {@link Integer#parseInt(String)}, 1522 * {@link Long#parseLong(String)}, {@link Float#parseFloat(String)} or 1523 * {@link Double#parseDouble(String)}. This method can be used instead of catching {@link java.text.ParseException} 1524 * when calling one of those methods.</p> 1525 * 1526 * <p>Hexadecimal and scientific notations are <strong>not</strong> considered parsable. 1527 * See {@link #isCreatable(String)} on those cases.</p> 1528 * 1529 * <p>{@code Null} and empty String will return <code>false</code>.</p> 1530 * 1531 * @param str the String to check. 1532 * @return {@code true} if the string is a parsable number. 1533 * @since 3.4 1534 */ 1535 public static boolean isParsable(final String str) { 1536 if (StringUtils.isEmpty(str)) { 1537 return false; 1538 } 1539 if (str.charAt(str.length() - 1) == '.') { 1540 return false; 1541 } 1542 if (str.charAt(0) == '-') { 1543 if (str.length() == 1) { 1544 return false; 1545 } 1546 return withDecimalsParsing(str, 1); 1547 } else { 1548 return withDecimalsParsing(str, 0); 1549 } 1550 } 1551 1552 private static boolean withDecimalsParsing(final String str, final int beginIdx) { 1553 int decimalPoints = 0; 1554 for (int i = beginIdx; i < str.length(); i++) { 1555 final boolean isDecimalPoint = str.charAt(i) == '.'; 1556 if (isDecimalPoint) { 1557 decimalPoints++; 1558 } 1559 if (decimalPoints > 1) { 1560 return false; 1561 } 1562 if (!isDecimalPoint && !Character.isDigit(str.charAt(i))) { 1563 return false; 1564 } 1565 } 1566 return true; 1567 } 1568 1569 /** 1570 * <p>Compares two {@code int} values numerically. This is the same functionality as provided in Java 7.</p> 1571 * 1572 * @param x the first {@code int} to compare 1573 * @param y the second {@code int} to compare 1574 * @return the value {@code 0} if {@code x == y}; 1575 * a value less than {@code 0} if {@code x < y}; and 1576 * a value greater than {@code 0} if {@code x > y} 1577 * @since 3.4 1578 */ 1579 public static int compare(int x, int y) { 1580 if (x == y) { 1581 return 0; 1582 } 1583 return x < y ? -1 : 1; 1584 } 1585 1586 /** 1587 * <p>Compares to {@code long} values numerically. This is the same functionality as provided in Java 7.</p> 1588 * 1589 * @param x the first {@code long} to compare 1590 * @param y the second {@code long} to compare 1591 * @return the value {@code 0} if {@code x == y}; 1592 * a value less than {@code 0} if {@code x < y}; and 1593 * a value greater than {@code 0} if {@code x > y} 1594 * @since 3.4 1595 */ 1596 public static int compare(long x, long y) { 1597 if (x == y) { 1598 return 0; 1599 } 1600 return x < y ? -1 : 1; 1601 } 1602 1603 /** 1604 * <p>Compares to {@code short} values numerically. This is the same functionality as provided in Java 7.</p> 1605 * 1606 * @param x the first {@code short} to compare 1607 * @param y the second {@code short} to compare 1608 * @return the value {@code 0} if {@code x == y}; 1609 * a value less than {@code 0} if {@code x < y}; and 1610 * a value greater than {@code 0} if {@code x > y} 1611 * @since 3.4 1612 */ 1613 public static int compare(short x, short y) { 1614 if (x == y) { 1615 return 0; 1616 } 1617 return x < y ? -1 : 1; 1618 } 1619 1620 /** 1621 * <p>Compares two {@code byte} values numerically. This is the same functionality as provided in Java 7.</p> 1622 * 1623 * @param x the first {@code byte} to compare 1624 * @param y the second {@code byte} to compare 1625 * @return the value {@code 0} if {@code x == y}; 1626 * a value less than {@code 0} if {@code x < y}; and 1627 * a value greater than {@code 0} if {@code x > y} 1628 * @since 3.4 1629 */ 1630 public static int compare(byte x, byte y) { 1631 return x - y; 1632 } 1633}