Java | Create an explicit addition function only using recursion and conditionals - java

Preface
By finding some free time in my schedule, I quested myself into improving my recursion skills (unfortunately). As practice, I want to recreate all the operators by using recursion, the first one being addition. Although I'm kind of stuck.
Question
As implied, I want to recreate the addition operator by only using recursion and conditionals. Although I got a good portion of the code done, there is still one problem as I included a single addition operator. Here is the code (which runs fine and adds as intended in all variations of positive, negative, and zero inputs). I also included some mediocre comments as help.
public class Test {
public static void main(String[] args) {
// Numbers to add
int firstNumb = -5, secondNumb = 3;
// Call the add function and save the result
int result = add(firstNumb, secondNumb);
// Print result
System.out.println(result);
}
/*
* Function recursively takes a number from 'giver' one at a time and
* "gives"/"adds" it to 'receiver'. Once nothing more to "give" (second == 0),
* then return the number that received the value, 'receiver'.
*/
public static int add(int receiver, int giver) {
/*
* Base Case since nothing more to add on. != to handle signed numbers
* instead of using > or <
*/
if (giver != 0) {
/*
* Recursive Call.
*
* The new 'giver' param is the incremental value of the number
* towards 0. Ex: -5 -> -4 , 5 -> 4 (so I guess it may decrement).
*
* The new 'receiver' param is the incremental value based on the
* opposite direction the 'giver' incremented (as to why the
* directionalIncrement() function needs both values to determine
* direction.
*/
return add(directionalIncrement(receiver, giver),
directionalIncrement(giver, -giver));
} else {
// Return 'receiver' which now contains all values from 'giver'
return receiver;
}
}
// Increments (or decrements) the 'number' based on the sign of the 'direction'
public static int directionalIncrement(int number, int direction) {
// Get incremental value (1 or -1) by dividing 'direction' by absolute
// value of 'direction'
int incrementalValue = direction / abs(direction);
// Increment (or decrement I guess)
return number + incrementalValue;
}
// Calculates absolute value of a number
public static int abs(int number) {
// If number is positive, return number, else make it positive by multiplying by -1 then return
number = (number > 0.0F) ? number : -number;
return number;
}
}
The problem is the line that contains return number + incrementalValue;. As mentioned before, the code works with this although doesn't meet my own specifications of not involving any addition operators.
I changed the line to return add(number, incrementalValue); but seems like it cannot break out of the recursion and indeed throws the title of this website, a StackOverflowException.
All help appreciated. Thanks in advance.
Note
Constraint does not include any implicit increment/decrement (i++/i--) nor does it include bitwise. Try and answer towards the specific problem I am having in my own implementation.

public static int add(int a, int b) {
if(b == 0) return a;
int sum = a ^ b; //SUM of two integer is A XOR B
int carry = (a & b) << 1; //CARRY of two integer is A AND B
return add(sum, carry);
}
Shamefully taken from here. All credit goes to its author.

public static int add (int a, int b) {
if (b == 0) return a;
if (b > a) return add (b, a);
add (++a, --b);
}
Just with ++/--.

Related

How to replace the overridden methods with a Recursive implementation

I want to use recursion in order to collapse the overridden add() methods in the code and allow the user to provide any number of terms.
I've made a couple of changes to my code, but I'm not getting the desired result.
Examples of user input and expected output.
Output (for input 3 + 4)
7.0
Output (for input 3 + 4 + 5)
12.0
The code I have:
import java.util.*;
public class Recursion {
public static void main(String args[]) {
Scanner input = new Scanner(System.in);
String exp = input.nextLine();
System.out.println(solver(exp.split(" ")));
}
public static double solver(String[] expression) {
double result = 0;
if (expression.length == 3) {
result = add(Double.parseDouble(expression[0]), Double.parseDouble(expression[2]));
}
else if (expression.length == 5) {
result = add(Double.parseDouble(expression[0]), Double.parseDouble(expression[2]),
Double.parseDouble(expression[4]));
}
else if (expression.length == 7) {
result = add(Double.parseDouble(expression[0]), Double.parseDouble(expression[2]),
Double.parseDouble(expression[4]), Double.parseDouble(expression[6]));
}
else if (expression.length == 9) {
result = add(Double.parseDouble(expression[0]), Double.parseDouble(expression[2]),
Double.parseDouble(expression[4]), Double.parseDouble(expression[6]),
Double.parseDouble(expression[8]));
}
else if (expression.length == 11) {
result = add(Double.parseDouble(expression[0]), Double.parseDouble(expression[2]),
Double.parseDouble(expression[4]), Double.parseDouble(expression[6]),
Double.parseDouble(expression[8]), Double.parseDouble(expression[10]));
}
return result;
}
public static double add(double a, double b) {return a + b;}
public static double add(double a, double b, double c) {return a + b + c;}
public static double add(double a, double b, double c, double d) {return a + b + c + d;}
public static double add(double a, double b, double c, double d, double e) {return a + b + c + d + e;}
public static double add(double a, double b, double c, double d, double e, double f) {return a + b + c + d + e + f;}
}
That's doable with recursion.
But before diving into recursive implementation, it's worth to find out how to solve this problem iteratively because it'll give you a better understanding of what the recursion does.
Firstly, I want to point out at issues with the code you've provided.
Your existing solution is brittle since it depends on the consistency of the user input, and it will fail because of the single additional white space or if a white space will be missing.
Another draw-back is that you have a lot of methods and with them, you are able to handle only a limited number of arguments in the given expression. Let's fix it.
Since your code is intended to perform the arithmetical addition, I think it'll be better to split the input on the plus symbol + and give a user a bit of freedom with white spaces.
For that, we need to pass the following regular expression into the split() method:
"\\s*\\+\\s*"
\s* - implies 0 or more white spaces;
\+ - plus symbol has a special meaning in regular expressions and needs to be escaped with a back-slash.
And since there's more than one arithmetical operation (and you also might want to implement others letter on). It's better to extract your the logic for splitting the user input into a separate method:
public static double add(String expression) {
return addIteratively(expression.split("\\s*\\+\\s*"));
}
expression.split() will return an array of numeric strings that will allow to substitute all your methods with a single method that expects a string array String[] or varargs String... expression (which will allow you to pass as an argument either an array of strings or arbitrary number of string values).
public static double addIteratively(String[] operands) {
double result = 0;
for (String next: operands) {
result += Double.parseDouble(next);
}
return result;
}
Now, when it's clear how to deal with this task iteratively (remember every problem and could be addressed using iteration is also eligible for recursion and vice versa) let's proceed with a quick recap on recursion.
Every recursive method consists of two parts:
Base case - that represents a simple edge-case (condition when recursion terminates) for which the outcome is known in advance.
Recursive case - a part of a solution where recursive calls are made and where the main logic resides.
To process the given array recursively, we can track the position in the array by passing it with each method call.
The base case will represent a situation when there's no more elements left in the array, i.e. current position is equal to the array's length. Since there's no element under the given position, the return is 0.
In the recursive case we need to parse the number under the current position and add the result of the recursive call with position incremented by 1 to it. That will give us the return value.
The recursive implementation might look that:
public static double addAsDouble(String[] operands, int pos) {
if (pos == operands.length) { // base case
return 0;
}
// recursive case
return Double.parseDouble(operands[pos]) + addAsDouble(operands, pos + 1);
}
Method responsible for splitting the user input.
public static double add(String expression) {
return addAsDouble(expression.split("\\s*\\+\\s*"), 0); // recursion starts at position 0
}
main() - here, you just need to call the add() providing a string inter by the user and bother of what is happening inside add. That makes code cleaner and easier to read.
public static void main(String args[]) {
Scanner input = new Scanner(System.in);
String exp = input.nextLine();
System.out.println(add(exp));
}
Output
3 + 4 +5
12.0
You are not passing the correct indexes to the various add methods. For example, if you want to add three numbers, you should do the following:
result = add(Double.parseDouble(expression[0]), Double.parseDouble(expression[1]), Double.parseDouble(expression[2]));

How to transfer an outside recursion program into a non-recursive form (using stack not CPS)?

there are many questions about how to convert recursive to non-recursive, and I also can convert some recursive programs to non-recursive form
note: I use an generalized way (user defined Stack), because I think it is easy to understand, and I use Java, so can not use GOTO keyword.
Things don't always go so well, when I meet the Backtracking, I am stuck. for example, The subset problem. and my code is here: recursive call with loop
when i use user defined Stack to turn it to non-recursive form. I do not know how to deal with the loop (in the loop existing recursive call).
I googled found that there is many methods such as CPS. and I know there is an iterative template of subset problem. but i only want to use user defined Stack to solve.
Can someone provide some clues to turn this kind of recursive(recursive with loop) to non-recursive form(by using user defined Stack, not CPS etc..) ?
here is my code recursive to non-recusive(Inorder-Traversal), because of there is no loop with recursive call, so i can easily do it. also when recursive program with a return value, I can use a reference and pass it to the function as a param. from the code, I use the Stack to simulated the recursive call, and use "state" variable to the next call point(because java does not allow using GOTO).
The following is the information I have collected. It seems that all of them does not satisfy the question I mentioned(some use goto that java not allowed, some is very simple recursive means that no nested recursive call or recursive call with loop ).
1 Old Dominion University
2 codeproject
----------------------------------Split Line--------------------------------------
Thks u all. after when I post the question... It took me all night to figure it out. here is my solution: non-recursive subset problem solution, and the comment of the code is my idea.
To sum up. what i stuck before is how to deal with the foo-loop, actually, we can just simply ignore it. because we are using loop+stack, we can do a simple judgment on whether to meet the conditions.
On your stack, have you thought about pushing i (the iteration variable)?
By doing this, when you pop this value, you know at which iteration of the loop you were before you pushed on the stack and therefore, you can iterate to the next i and continue your algorithm.
Non-negative numbers only for simplicity. (Also no IntFunction.)
The power function, as defined here, is a very simple case.
int power(int x, int exponent) {
if (exponent == 0) {
return 1;
} else if (exponent % 2 == 0) {
int y = power(x, exponent /2);
return y * y;
} else {
return x * power(x, exponent - 1);
}
}
Now the stack is there to do in the reverse order to a partial result, what you did in recursion with the result.
int power(final int x, int exponent) {
Stack<Function<Integer, Integer>> opStack = new Stack<>();
final Function<Integer, Integer> square = n -> n * n;
final Function<Integer, Integer> multiply = n -> x * n;
while (exponent > 0) {
if (exponent % 2 == 0) {
exponent /= 2;
opStack.push(square);
} else {
--exponent;
opStack.push(multiply);
}
}
int result = 1;
while (!opStack.isEmpty()) {
result = opStack.pop().apply(result);
}
return result;
}
An alternative would be to "encode" the two branches of if-else (odd/even exponent) by a boolean:
int power(final int x, int exponent) {
BooleanStack stack = new BooleanStack<>();
while (exponent > 0) {
boolean even = exponent % 2 == 0;
stack.push(even);
if (even) {
exponent /= 2;
} else {
--exponent;
}
}
int result = 1;
while (!stack.isEmpty()) {
result *= stack.pop() ? result : x;
}
return result;
}
So one has to distinghuish:
what one does to prepare the recursive arguments
what one does with the partial results of the recursive calls
how one can merge/handle several recursive calls in the function
exploit nice things, like x being a final constant
Not difficult, puzzling maybe, so have fun.

Return inside of recursive function doesn't 'work' if short if is used

I have this odd issue I can't explain to myself, when using short if inside of return. This code (see below) should return the value 55 but instead it just returns the argument 10 which I passed to it by value.
I already debugged the function and the recursion works as intended but it never adds the + 1 to the return value.
public static int add(int i) {
return i == 0 ? 0 : add(i - 1) + 1;
}
public static void main(String[] args) {
System.out.println(add(10)); // returns 10
}
How come this doesn't work?
Your code does what you're telling it to. At each recursion step it reduces one from the counter and adds 1 to the result - since it's counting i times, it'll return i.
What you're trying to do is sum the numbers from 0 to i. In order to do this you need to add i and not 1 to the sum each time.
public static int add(int i) {
return i == 0 ? 0 : add(i - 1) + i; // <- like this
}
Since this is likely an exercise, consider implementing factorial recursively to make sure you understand the concept (that is, a function that takes n and returns n * (n-1) * (n-2) ... and so on.

Given a number, find which numbers below it divide it using recursion

I can't seem to figure this one out. I need to count how many numbers below a given number in which it is divisible.
Here is what I've tried:
public int testing(int x) {
if (x == 0) {
System.out.println("zero");
return x;
}
else if ((x % (x-1)) == 0) {
System.out.println("does this work?");
x--;
}
return testing(x-1);
}
That doesn't work and I don't know where to go from here. Anyone know what to do?
This is what is wrong:
public int testing(int x) {
If you want to make it recursive, you need to pass both the number to test and the number that you are currently checking. The first one will not change through the recursion, the second one will decrement. You cannot do what you express with only one parameter (unless you use a global variable).
This is not a task that should be solved with recursion.
If you MUST use recursion, the simplest way to do it is to have a second parameter, which is essentially an "I have checked until this number". Then you can increase/decrease this (depending on if you start at 0 or the initial number) and call the recursive on that.
Thing is, Java isn't a functional language, so doing all this is actually kind of dumb, so whoever gave you this exercise probably needs a bop on the head.
Your problem is that your expression x % (x - 1) is using the "current" value of x, which decrements on every call to the recursive function. Your condition will be false all the way down to 2 % (2 - 1).
Using a for loop is a much better way to handle this task (and look at the Sieve of Eratosthenes), but if you really have to use recursion (for homework), you'll need to pass in the original value being factored as well as the current value being tried.
You have a problem with your algorithm. Notice the recursion only ends when x == 0, meaning that your function will always return 0 (if it returns at all).
In addition, your algorithm doesn't seem to make any sense. You are basically trying to find all factors of a number, but there's only one parameter, x.
Try to make meaningful names for your variables and the logic will be easier to read/follow.
public int countFactors(int number, int factorToTest, int numFactors)
{
if (factorToTest == 0) // now you are done
return numFactors;
else
// check if factorToTest is a factor of number
// adjust the values appropriately and recurse
}
There is no need to use recursion here. Here's a non-recursive solution:
public int testing(int n) {
int count = 0;
for (int i = 1; i < n; i++)
if (n % i == 0)
count++;
return count;
}
BTW, you should probably call this something other than testing.
Using recursion:
private static int getFactorCount(int num) {
return getFactorCount(num, num - 1);
}
private static int getFactorCount(int num, int factor) {
return factor == 0 ? 0 : (num % factor == 0 ? 1 : 0)
+ getFactorCount(num, factor - 1);
}
public static void main(String[] args) {
System.out.println(getFactorCount(20)); // gives 5
System.out.println(getFactorCount(30)); // gives 7
}

Check whether a string is parsable into Long without try-catch?

Long.parseLong("string") throws an error if string is not parsable into long.
Is there a way to validate the string faster than using try-catch?
Thanks
You can create rather complex regular expression but it isn't worth that. Using exceptions here is absolutely normal.
It's natural exceptional situation: you assume that there is an integer in the string but indeed there is something else. Exception should be thrown and handled properly.
If you look inside parseLong code, you'll see that there are many different verifications and operations. If you want to do all that stuff before parsing it'll decrease the performance (if we are talking about parsing millions of numbers because otherwise it doesn't matter). So, the only thing you can do if you really need to improve performance by avoiding exceptions is: copy parseLong implementation to your own function and return NaN instead of throwing exceptions in all correspondent cases.
From commons-lang StringUtils:
public static boolean isNumeric(String str) {
if (str == null) {
return false;
}
int sz = str.length();
for (int i = 0; i < sz; i++) {
if (Character.isDigit(str.charAt(i)) == false) {
return false;
}
}
return true;
}
You could do something like
if(s.matches("\\d*")){
}
Using regular expression - to check if String s is full of digits.
But what do you stand to gain? another if condition?
org.apache.commons.lang3.math.NumberUtils.isParsable(yourString) will determine if the string can be parsed by one of: Integer.parseInt(String), Long.parseLong(String), Float.parseFloat(String) or Double.parseDouble(String)
Since you are interested in Longs you could have a condition that checks for isParsable and doesn't contain a decimal
if (NumberUtils.isParsable(yourString) && !StringUtils.contains(yourString,".")){ ...
This is a valid question because there are times when you need to infer what type of data is being represented in a string. For example, you may need to import a large CSV into a database and represent the data types accurately. In such cases, calling Long.parseLong and catching an exception can be too slow.
The following code only handles ASCII decimal:
public class LongParser {
// Since tryParseLong represents the value as negative during processing, we
// counter-intuitively want to keep the sign if the result is negative and
// negate it if it is positive.
private static final int MULTIPLIER_FOR_NEGATIVE_RESULT = 1;
private static final int MULTIPLIER_FOR_POSITIVE_RESULT = -1;
private static final int FIRST_CHARACTER_POSITION = 0;
private static final int SECOND_CHARACTER_POSITION = 1;
private static final char NEGATIVE_SIGN_CHARACTER = '-';
private static final char POSITIVE_SIGN_CHARACTER = '+';
private static final int DIGIT_MAX_VALUE = 9;
private static final int DIGIT_MIN_VALUE = 0;
private static final char ZERO_CHARACTER = '0';
private static final int RADIX = 10;
/**
* Parses a string representation of a long significantly faster than
* <code>Long.ParseLong</code>, and avoids the noteworthy overhead of
* throwing an exception on failure. Based on the parseInt code from
* http://nadeausoftware.com/articles/2009/08/java_tip_how_parse_integers_quickly
*
* #param stringToParse
* The string to try to parse as a <code>long</code>.
*
* #return the boxed <code>long</code> value if the string was a valid
* representation of a long; otherwise <code>null</code>.
*/
public static Long tryParseLong(final String stringToParse) {
if (stringToParse == null || stringToParse.isEmpty()) {
return null;
}
final int inputStringLength = stringToParse.length();
long value = 0;
/*
* The absolute value of Long.MIN_VALUE is greater than the absolute
* value of Long.MAX_VALUE, so during processing we'll use a negative
* value, then we'll multiply it by signMultiplier before returning it.
* This allows us to avoid a conditional add/subtract inside the loop.
*/
int signMultiplier = MULTIPLIER_FOR_POSITIVE_RESULT;
// Get the first character.
char firstCharacter = stringToParse.charAt(FIRST_CHARACTER_POSITION);
if (firstCharacter == NEGATIVE_SIGN_CHARACTER) {
// The first character is a negative sign.
if (inputStringLength == 1) {
// There are no digits.
// The string is not a valid representation of a long value.
return null;
}
signMultiplier = MULTIPLIER_FOR_NEGATIVE_RESULT;
} else if (firstCharacter == POSITIVE_SIGN_CHARACTER) {
// The first character is a positive sign.
if (inputStringLength == 1) {
// There are no digits.
// The string is not a valid representation of a long value.
return null;
}
} else {
// Store the (negative) digit (although we aren't sure yet if it's
// actually a digit).
value = -(firstCharacter - ZERO_CHARACTER);
if (value > DIGIT_MIN_VALUE || value < -DIGIT_MAX_VALUE) {
// The first character is not a digit (or a negative sign).
// The string is not a valid representation of a long value.
return null;
}
}
// Establish the "maximum" value (actually minimum since we're working
// with negatives).
final long rangeLimit = (signMultiplier == MULTIPLIER_FOR_POSITIVE_RESULT)
? -Long.MAX_VALUE
: Long.MIN_VALUE;
// Capture the maximum value that we can multiply by the radix without
// overflowing.
final long maxLongNegatedPriorToMultiplyingByRadix = rangeLimit / RADIX;
for (int currentCharacterPosition = SECOND_CHARACTER_POSITION;
currentCharacterPosition < inputStringLength;
currentCharacterPosition++) {
// Get the current digit (although we aren't sure yet if it's
// actually a digit).
long digit = stringToParse.charAt(currentCharacterPosition)
- ZERO_CHARACTER;
if (digit < DIGIT_MIN_VALUE || digit > DIGIT_MAX_VALUE) {
// The current character is not a digit.
// The string is not a valid representation of a long value.
return null;
}
if (value < maxLongNegatedPriorToMultiplyingByRadix) {
// The value will be out of range if we multiply by the radix.
// The string is not a valid representation of a long value.
return null;
}
// Multiply by the radix to slide all the previously parsed digits.
value *= RADIX;
if (value < (rangeLimit + digit)) {
// The value would be out of range if we "added" the current
// digit.
return null;
}
// "Add" the digit to the value.
value -= digit;
}
// Return the value (adjusting the sign if needed).
return value * signMultiplier;
}
}
You can use java.util.Scanner
Scanner sc = new Scanner(s);
if (sc.hasNextLong()) {
long num = sc.nextLong();
}
This does range checking etc, too. Of course it will say that "99 bottles of beer" hasNextLong(), so if you want to make sure that it only has a long you'd have to do extra checks.
This case is common for forms and programs where you have the input field and are not sure if the string is a valid number. So using try/catch with your java function is the best thing to do if you understand how try/catch works compared to trying to write the function yourself. In order to setup the try catch block in .NET virtual machine, there is zero instructions of overhead, and it is probably the same in Java. If there are instructions used at the try keyword then these will be minimal, and the bulk of the instructions will be used at the catch part and that only happens in the rare case when the number is not valid.
So while it "seems" like you can write a faster function yourself, you would have to optimize it better than the Java compiler in order to beat the try/catch mechanism you already use, and the benefit of a more optimized function is going to be very minimal since number parsing is quite generic.
If you run timing tests with your compiler and the java catch mechanism you already described, you will probably not notice any above marginal slowdown, and by marginal I mean it should be almost nothing.
Get the java language specification to understand the exceptions more and you will see that using such a technique in this case is perfectly acceptable since it wraps a fairly large and complex function. Adding on those few extra instructions in the CPU for the try part is not going to be such a big deal.
I think that's the only way of checking if a String is a valid long value. but you can implement yourself a method to do that, having in mind the biggest long value.
There are much faster ways to parse a long than Long.parseLong. If you want to see an example of a method that is not optimized then you should look at parseLong :)
Do you really need to take into account "digits" that are non-ASCII?
Do you really need to make several methods calls passing around a radix even tough you're probably parsing base 10?
:)
Using a regexp is not the way to go: it's harder to determine if you're number is too big for a long: how do you use a regexp to determine that 9223372036854775807 can be parsed to a long but that 9223372036854775907 cannot?
That said, the answer to a really fast long parsing method is a state machine and that no matter if you want to test if it's parseable or to parse it. Simply, it's not a generic state machine accepting complex regexp but a hardcoded one.
I can both write you a method that parses a long and another one that determines if a long can be parsed that totally outperforms Long.parseLong().
Now what do you want? A state testing method? In that case a state testing method may not be desirable if you want to avoid computing twice the long.
Simply wrap your call in a try/catch.
And if you really want something faster than the default Long.parseLong, write one that is tailored to your problem: base 10 if you're base 10, not checking digits outside ASCII (because you're probably not interested in Japanese's itchi-ni-yon-go etc.).
Hope this helps with the positive values. I used this method once for validating database primary keys.
private static final int MAX_LONG_STR_LEN = Long.toString(Long.MAX_VALUE).length();
public static boolean validId(final CharSequence id)
{
//avoid null
if (id == null)
{
return false;
}
int len = id.length();
//avoid empty or oversize
if (len < 1 || len > MAX_LONG_STR_LEN)
{
return false;
}
long result = 0;
// ASCII '0' at position 48
int digit = id.charAt(0) - 48;
//first char cannot be '0' in my "id" case
if (digit < 1 || digit > 9)
{
return false;
}
else
{
result += digit;
}
//start from 1, we already did the 0.
for (int i = 1; i < len; i++)
{
// ASCII '0' at position 48
digit = id.charAt(i) - 48;
//only numbers
if (digit < 0 || digit > 9)
{
return false;
}
result *= 10;
result += digit;
//if we hit 0x7fffffffffffffff
// we are at 0x8000000000000000 + digit - 1
// so negative
if (result < 0)
{
//overflow
return false;
}
}
return true;
}
Try to use this regular expression:
^(-9223372036854775808|0)$|^((-?)((?!0)\d{1,18}|[1-8]\d{18}|9[0-1]\d{17}|92[0-1]\d{16}|922[0-2]\d{15}|9223[0-2]\d{14}|92233[0-6]\d{13}|922337[0-1]\d{12}|92233720[0-2]\d{10}|922337203[0-5]\d{9}|9223372036[0-7]\d{8}|92233720368[0-4]\d{7}|922337203685[0-3]\d{6}|9223372036854[0-6]\d{5}|92233720368547[0-6]\d{4}|922337203685477[0-4]\d{3}|9223372036854775[0-7]\d{2}|922337203685477580[0-7]))$
It checks all possible numbers for Long.
But as you know in Java Long can contain additional symbols like +, L, _ and etc. And this regexp doesn't validate these values. But if this regexp is not enough for you, you can add additional restrictions for it.
Guava Longs.tryParse("string") returns null instead of throwing an exception if parsing fails. But this method is marked as Beta right now.
You could try using a regular expression to check the form of the string before trying to parse it?
A simple implementation to validate an integer that fits in a long would be:
public static boolean isValidLong(String str) {
if( str==null ) return false;
int len = str.length();
if (str.charAt(0) == '+') {
return str.matches("\\+\\d+") && (len < 20 || len == 20 && str.compareTo("+9223372036854775807") <= 0);
} else if (str.charAt(0) == '-') {
return str.matches("-\\d+") && (len < 20 || len == 20 && str.compareTo("-9223372036854775808") <= 0);
} else {
return str.matches("\\d+") && (len < 19 || len == 19 && str.compareTo("9223372036854775807") <= 0);
}
}
It doesn't handle octal, 0x prefix or so but that is seldom a requirement.
For speed, the ".match" expressions are easy to code in a loop.

Categories

Resources