How can I avoid a NumberFormatException in Java? - 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

Related

How to change decimal value string into int without loosing decimal values?

I am working on a pretty old Java application and I can not change Integer field to something else which can hold decimal values, so I need to convert some decimal string like "100.00", "3.33" "33.44" to Integer without loosing fractional values.
#Test
public void NumberFormatTest(){
String stringValue = "100.00";
int testTest = ? //what I can do here to get exact 100.00 in testTest variable ?
log.info("outPutValue {} ", testTest);
}
Currently its using Integer.parseInt(stringValue) and this is throwing
java.lang.NumberFormatException: For input string: "100.00"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
I am working on pretty old java code application and I can not change Integer field to something else which can hold decimal values
That is because int can only hold whole numbers. For decimal values you need to use float or double:
String s = "3.33";
double d = Double.parseDouble(s);
Alternatively, you might want to look into BigDecimal. Depending on your exact needs, this might be a better fit.
p.s. int, float and double are primitive types. Integer, Float and Double are class wrapper for those types. These are two different things. I recommend you read more about these differences to gain a better understanding.

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!

Check if number is too large or not a number

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)

Working on a calculator in java and taking the values as String

like "1+23"
parse to double for example.. then calculate..
but when i have a decimal the program crashes for example "1.1+2" the program glitches on the 1.1 when i'm parsing it
if(s.contains("+"))
{
int n = s.indexOf("+");
String w1 = s.substring(0,n);
String w2 = s.substring(n+1,s.length());
part1= (long) Double.parseDouble(w1);
part2 = (long)Double.parseDouble(w2);
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "1.1"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
You probably use Integer.parseInt(). If that's not the case, then you need to specify a lot more detail (how does it crash, post the stack trace, post the code).
You need to switch to either floating point numbers (Double.parseDouble()) or to BigDecimal (new BigDecimal()).
why are you casting from a double to long? that will result in your number being truncated. in the case of 1.1 you will get 1. What you should do is use the following:
Float.parseFloat(w1);
where w1 is your floating point value.
you cannot have part1 be a long value, since long values cannot hold floating points. part1 must be a float.

Problems using DecimalFormat

I am having problems using DecimalFormat when I am going to print out coefficients after a regression.
Here is the part of the code that is facing problems;
DecimalFormat twoDForm = new DecimalFormat("0.00");
private double s(double d){
return Double.valueOf(twoDForm.format(d));
}
and here is the error message in eclipse;
Exception in thread "main" java.lang.NumberFormatException: For input string: "0,16"
at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source)
at java.lang.Double.valueOf(Unknown Source)
at model.ARF2.s(ARF2.java:126)
at model.ARF2.printBestModel(ARF2.java:114)
at testing.testclass3.bestForecastingModel(testclass3.java:69)
at testing.testclass3.main(testclass3.java:36)
Please let me know if anyone has any surgestions on how to fix the code. I want two decimals on my coefficients.
Thank you
Lars
use:
DecimalFormat twoDForm = new DecimalFormat("#.##");
DecimalFormatSymbols dfs = new DecimalFormatSymbols();
dfs.setDecimalSeparator('.');
twoDForm.setDecimalFormatSymbols(dfs);
http://download.oracle.com/javase/1.4.2/docs/api/java/text/DecimalFormat.html
The following excerpt appears to be part of your problem:
To obtain a NumberFormat for a
specific locale, including the default
locale, call one of NumberFormat's
factory methods, such as
getInstance(). In general, do not call
the DecimalFormat constructors
directly, since the NumberFormat
factory methods may return subclasses
other than DecimalFormat. If you need
to customize the format object, do
something like this:
NumberFormat f = NumberFormat.getInstance(loc);
if (f instanceof DecimalFormat) {
((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
}
You may want to use the applyPattern method:
applyPattern
public void applyPattern(String
pattern) Apply the given pattern to
this Format object. A pattern is a
short-hand specification for the
various formatting properties. These
properties can also be changed
individually through the various
setter methods. There is no limit to
integer digits are set by this
routine, since that is the typical
end-user desire; use setMaximumInteger
if you want to set a real value. For
negative numbers, use a second
pattern, separated by a semicolon
Example "#,#00.0#" -> 1,234.56
This means a minimum of 2 integer
digits, 1 fraction digit, and a
maximum of 2 fraction digits.
Example: "#,#00.0#;(#,#00.0#)" for
negatives in parentheses.
In negative patterns, the minimum and
maximum counts are ignored; these are
presumed to be set in the positive
pattern.
Throws: NullPointerException - if
pattern is null
IllegalArgumentException - if the
given pattern is invalid.
You are encountering an i18n issue. DecimalFormat is using your default locale which specifies the decimal separator as ,. However, the Double.valueOf does not use the locale. It always expects that the decimal separator is ..
If you want to parse a string formatted with DecimalFormat then you need to use DecimalFormat.parse
I think what you intended to do is:
private static String s(double d) {
return twoDForm.format(d);
}
Are you trying to format the number? Or round it? If you're formatting it, shouldn't your "s" method (bad name IMO, btw, but it's private, so it's your call) return a java.lang.String instead of a double?
Check your Locale.
DecimalFormat twoDForm = new DecimalFormat("0.00");
private double s(double d){
String doubleString = displayNumberAmount(twoDForm.format(d));
return Double.valueOf(doubleString);
}
public static String displayNumberAmount(String amount) {
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.CANADA_FRENCH);
Number number = 0;
try {
number = numberFormat.parse(amount);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return String.format(Locale.US, "%1$,.2f", number);
}

Categories