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