/** * NumberTools * Copyright 2012 by Sebastian Gaebel * First released 21.05.2012 at http://yacy.net * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program in the file lgpl21.txt * If not, see <http://www.gnu.org/licenses/>. */ package net.yacy.cora.util; import java.util.Random; public class NumberTools { /** * this method replaces Long.parseLong/2 where a substring of decimal numbers shall be parsed * Strings are also auto-trimmed, that means parsing stops at trailing spaces without throwing a NumberFormatException * leading spaces are skip'd and parse stops at first none digit character * @param s * @param startPos * @return the number * @throws NumberFormatException */ public static final long parseLongDecSubstring(String s) throws NumberFormatException { if (s == null) throw new NumberFormatException(s); return parseLongDecSubstring(s, 0, s.length()); } public static final long parseLongDecSubstring(String s, int startPos) throws NumberFormatException { if (s == null) throw new NumberFormatException(s); return parseLongDecSubstring(s, startPos, s.length()); } public static final long parseLongDecSubstring(String s, int startPos, final int endPos) throws NumberFormatException { if (s == null || endPos > s.length() || endPos <= startPos) throw new NumberFormatException(s); long result = 0; boolean negative = false; int i = startPos; long limit = -Long.MAX_VALUE; final long multmin; int digit; char c; while (s.charAt(i) == ' ') i++; // skip leading blanks char firstChar = s.charAt(i); if (firstChar < '0') { if (firstChar == '-') { negative = true; limit = Long.MIN_VALUE; } else if (firstChar != '+') throw new NumberFormatException(s); i++; if (endPos == i) throw new NumberFormatException(s); } multmin = limit / 10; while (i < endPos) { c = s.charAt(i++); if (c < '0' || c > '9') break; // stop at first non digit character digit = c - '0'; if (digit < 0 || digit > 9 || result < multmin) throw new NumberFormatException(s); result *= 10; if (result < limit + digit) throw new NumberFormatException(s); result -= digit; } return negative ? result : -result; } public static final int parseIntDecSubstring(String s) throws NumberFormatException { if (s == null) throw new NumberFormatException(s); return parseIntDecSubstring(s, 0, s.length()); } public static final int parseIntDecSubstring(String s, int startPos) throws NumberFormatException { if (s == null) throw new NumberFormatException(s); return parseIntDecSubstring(s, startPos, s.length()); } public static final int parseIntDecSubstring(String s, int startPos, final int endPos) throws NumberFormatException { if (s == null || endPos > s.length() || endPos <= startPos) throw new NumberFormatException(s); int result = 0; boolean negative = false; int i = startPos; int limit = -Integer.MAX_VALUE; final int multmin; int digit; char c; while (s.charAt(i) == ' ') i++; // skip leading blanks char firstChar = s.charAt(i); if (firstChar < '0') { if (firstChar == '-') { negative = true; limit = Integer.MIN_VALUE; } else if (firstChar != '+') throw new NumberFormatException(s); i++; if (endPos == i) throw new NumberFormatException(s); } multmin = limit / 10; while (i < endPos) { c = s.charAt(i++); if (c < '0' || c > '9') break; // stop at first non digit character digit = c - '0'; if (digit < 0 || digit > 9 || result < multmin) throw new NumberFormatException(s); result *= 10; //result = (result << 3) + (result << 1); if (result < limit + digit) throw new NumberFormatException(s); result -= digit; } return negative ? result : -result; } public static void main(String[] args) { System.out.println("the number is " + parseLongDecSubstring("number=78 ", 7)); System.out.println("the number is " + parseIntDecSubstring("number=78x ", 7, 9)); Random r = new Random(1); String[] s = new String[1000000]; for (int i = 0; i < s.length; i++) s[i] = "abc " + Integer.toString(r.nextInt()) + " "; long d = 0; long t0 = System.currentTimeMillis(); for (String element : s) { d += Integer.parseInt(element.substring(4).trim()); } System.out.println("java: " + d + " - " + (System.currentTimeMillis() - t0) + " millis"); d = 0; t0 = System.currentTimeMillis(); for (String element : s) { d += parseIntDecSubstring(element, 4); } System.out.println("cora: " + d + " - " + (System.currentTimeMillis() - t0) + " millis"); r = new Random(1); for (int i = 0; i < s.length; i++) s[i] = Integer.toString(r.nextInt()); d = 0; t0 = System.currentTimeMillis(); for (String element : s) { d += Integer.parseInt(element); } System.out.println("java: " + d + " - " + (System.currentTimeMillis() - t0) + " millis"); d = 0; t0 = System.currentTimeMillis(); for (String element : s) { d += parseIntDecSubstring(element); } System.out.println("cora: " + d + " - " + (System.currentTimeMillis() - t0) + " millis"); } }