/**
* 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");
}
}