Check if number is too large or not a number - java

I am trying to parse a string safely,
public <T> long safeParseLong(T s){
try {
return Long.parseLong(s.toString());
}catch (NumberFormatException e){
return 0;
}
}
This will always work and if the string is not parsable, it will return 0.
However, is there a way to know what the reason is for it to be unparsable? Specifically, I want to know if it is not a number at all ("foo") or the number is too large (≥ 9223372036854775808).

The Long.parseLong method will throw a NumberFormatException if the string isn't a number or if the number wouldn't fit in a long.
If the exception is thrown, then test whether the string fits the regular expression for a number, "[+-]?[0-9]+". If it matches, it's a number that couldn't fit in a long. If it doesn't match, then it wasn't a number at all, e.g. "foo".
boolean isNumber = s.toString().matches("[+-]?[0-9]+");
But you are returning 0 if there was an error. This is indistinguishable from if the content of the string were "0". Perhaps it would be better to let an exception be thrown from this method. But instead of a NumberFormatException, you could create and throw a NotANumberException if it's not a numeric string, or a NumberMagnitudeTooLargeException if the parsing failed because it's too large to fit in a long.

Unfortunately, Long.parseLong will throw NumberFormatException in any case.
Long.parseLong(new String(new BigInteger(Long.toString(Long.MAX_VALUE)).add(new BigInteger("1")).toString()));
results in:
Exception in thread "main" java.lang.NumberFormatException: For input string: "9223372036854775808"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Long.parseLong(Unknown Source)
at java.lang.Long.parseLong(Unknown Source)
at Main.main(Main.java:13)

Related

If a String containing a number bigger than Integer.MAX_VALUE

I want to find if given String "99999999999999999999999999" or any massive number which would not fit in any datatype.I would like to find if that number is bigger than Integer.MAX_VALUE
Use BigInteger
BigInteger maxInt = BigInteger.valueOf(Integer.MAX_VALUE);
BigInteger value = new BigInteger("whatever");
if (value.compareTo(maxInt) > 0)
{
// larger
}
You could construct a BigInteger object from the string and then compare that BigInteger to Integer.MAX_VALUE.
You can call parseInt and catch NumberFormatException, which will be thrown if the number is too large (though it will also be thrown if the String has non-numeric characters).
If you want to avoid the exception, you can run the following checks:
If the String has more than 10 characters (or 11 if the first character is '-' or '+'), it must be larger than Integer.MAX_VALUE or smaller than Integer.MIN_VALUE.
Otherwise, call Long.parseLong() and compare the result to Integer.MAX_VALUE.
You can parse it as an int and catch an exception or BigInteger, or you can do a String comparison.
static final String MAX_INT_STR = Integer.toString(Integer.MAX_VALUE);
public static boolean checkInt(String s) {
return s.length() > MAX_INT_STR.length() || s.compareTo(MAX_INT_STR) > 0;
}
This could be used to avoid throwing some Exceptions before trying to parse it.
NOTE: This doesn't check that it only contains digits, but if it's a positive number it will check it is in bounds without parsing the string.
Try the following code to check if it's too big to fit inside an integer:
String num = "99999999999999999999999999";
try {
Integer.parseInt(num);
} catch(NumberFormatException ex) {
System.out.println("String did not fit in integer datatype");
}
This code will attempt to parse num into an integer, we can catch whenever that goes wrong and execute code when that happens (in this case a simple println).
From parseInt():
Throws: NumberFormatException - if the string does not contain a
parsable integer.

Why am I getting an error when checking if a string can be an double [duplicate]

This question already has answers here:
What is a NumberFormatException and how can I fix it?
(9 answers)
Closed 4 years ago.
Hey guys im pretty new to coding but one of my projects is to check to see if a string can be parse into a double. It keeps printing an error when trying running the program.
Here is the code:
public static void main(String[] args) {
SimpleReader in = new SimpleReader1L();
SimpleWriter out = new SimpleWriter1L();
// Constant entered in by user as a string
out.println("Welcome to constant approximator");
out.println("Please enter in a constant to be estimated");
String realConstant = in.nextLine();
//Double variable created in order to reassign later
double test = 0;
//FormatChecker class and canParseDouble verifies if the string is truly a double. boolean method.
FormatChecker.canParseDouble(realConstant);
//Test reassign and converts
test = Double.parseDouble(realConstant);
out.print(test);
in.close();
out.close();
}
}
Here is the error:
Exception in thread "main" java.lang.NumberFormatException: For input string: "pi"
at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source)
at sun.misc.FloatingDecimal.parseDouble(Unknown Source)
at java.lang.Double.parseDouble(Unknown Source)
at ABCDGuesser1Test.main(ABCDGuesser1Test.java:36)
It happens because you type pi which is not recognized as π (pi) constant. What have you typed was a String and these characters are not convertible to a number.
If you want to enter any number including the special constant like pi, you have to check first if the input is a Number or String. In case it's String, you can try to match it with a defined constant like π or e and use their defined value in Java such as Math.PI.
You should use the result of canParseDouble() not just call it. Something like this, I think:
if (FormatChecker.canParseDouble(realConstant)) {
test = Double.parseDouble(realConstant);
out.println(test);
}
As you say:
//FormatChecker class and canParseDouble verifies if the string is truly a double. boolean method.
FormatChecker.canParseDouble(realConstant);
You know that this line calls a boolean method and will then return either true or false. However, you do not do any use of this returned value. If so, what's the point of even calling the function, right?
You are trying to check if the string realConstant is a double, the method checks it but you simply ignore it, here. I believe you have an error because whether it is truly a double or not, the rest of the code will run. In the case where the string is not actually a double, an error will appear since the rest of the code cannot compile.
You should then use an if statement such as:
if (FormatChecker.canParseDouble(realConstant)) {
test = Double.parseDouble(realConstant);
out.println(test);
}
Also, I do not think you should expect an input of "pi" to return a double!

Java Fractions, again

Yesterday, I attempted to do this one way...today I am trying another and I am still stuck. I have to find a way of doing this using integer division and mod. Here is my code followed by the error messages.
public int evaluateFraction(int w, int n, int d)
throws NumberFormatException
{
whole = w;
numerator = n;
denominator = d;
return portion2;
}
Tester
input = JOptionPane.showInputDialog("Enter");
portion2 = Integer.parseInt(input);`
error messages:
Exception in thread "main" java.lang.NumberFormatException: For input string: "1 1/8"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.parseInt(Integer.java:527)
at ClientCode.main(ClientCode.java:43)
Java Result: 1
What on earth am I doing wrong now?
Integer.parseInt is able to parse only valid integer strings. If the input string contains anything other than digits then it will throw NumberFormatException.
You are trying to parse an expression 1 1/8, which is not a valid integer string.
"1 1/8" is not a number. 1 and 8 are, whitespace and / are not. You need to parse such expression by hand.
1 1/8 is not an integer, Integer.parseInt can perform well in the only one case, if data is valid.
Don't know, what result you expect but you either need some other method or parse it yourself.

Converting a string array to a large number array

So, in Java I have a large number in the command argument, let's say 12345678910, and I cannot use bigInteger, and I already did:
String[] g = args[1].split("");
So, my string is put in a string array. But, I cannot use:
int[] ginormintOne = new int[g.length];
for(int n = 0; n < g.length; n++) {
ginormintOne[n] = Integer.parseInt(g[n]);
}
It gives me this:
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at Ginormint.main(Ginormint.java:67)
I think my numbers are too large for int. Any idea on how to convert it to a large number array?
You are splitting on an empty string. For example,
"123 456".split("")
results in this array:
["" "1" "2" "3" " " "4" "5" "6"]
This is where your exception comes from.
The first element of the array from args[1].split("") is an empty string that to my opinion causes the exception java.lang.NumberFormatException since it cannot be converted to an Integer
Use Long.parseLong instead of Integer.parseInt and a long[] instead of Long.parseLong.
But that said, the NumberFormatException indicates the failure is because you're passing it an empty string. Are you sure you're splitting the string correctly, or that splitting is even necessary? The args array in main is already split on spaces, assuming that's where args is coming from.

How can I avoid a NumberFormatException in Java?

i searched, i found, but it all didn't work. my problem is that the NumberFormatException is thrown while I want to cast from String to double.
The string array atomized contains many strings and I tried to make an output before to make them visible so I could be sure there is data. the only problem is the double value. it is something like 5837848.3748980 but the valueOf method always throws the exception here. I have no idea why.
try
{
int key = Integer.valueOf(atomized[0]);
double value = Double.valueOf(atomized[1].trim());
int role = Integer.valueOf(atomized[2]);
Double newAccountState = this.bankKonto.charge(key, value, role);
System.out.println("NEW Account State "+newAccountState);
this.answerClient(newAccountState.toString());
}
catch (NumberFormatException e)
{
System.out.println(e.getClass().toString()+" "+e.getMessage());
}
Exception output:
java.lang.NumberFormatException: For input string: "109037.0"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.valueOf(Unknown Source)
at vsys.ue02.server.Bank.computeData(Bank.java:122)
at vsys.ue02.server.Bank.run(Bank.java:160)
It works fine here. So I'd assume your system locale has , rather than . for decimal separator. To avoid these things you can use DecimalFormat:
new DecimalFormat().parse("5837848.3748980");
Judging by the name of your variable - account - I assume you are dealing with money. You must never use floating point types to represent money. Use BigDecimal, or possibly int
This is a starting point for using DecimalFormat to convert strings to numbers. Also, if you are dealing with money and currencies, you should consider using BigDecimal instead of double.
You are using Integer.parseInt on a number with a decimal point - that is not a valid integer - visible in your stack trace

Categories