NumberFormatException: For input string: "5,2" - android

Please help me with this issue. I am adding code snippet and crash log here.
Code:
if (rssi <= -30 && rssi >= -90) {
double len = ((rssi + 20) * -1) / 10.0;
DecimalFormat decimalFormat = new DecimalFormat("#.##");
float twoDigitsF = Float.valueOf(decimalFormat.format(len));
return String.valueOf(twoDigitsF);
}
I am getting the exception at the line
float twoDigitsF = Float.valueOf(decimalFormat.format(len));
Here I am attaching my logs
Fatal Exception: java.lang.NumberFormatException: For input string: "5,2"
at java.lang.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1306)
at java.lang.Float.valueOf(Float.java:424)
at com.app.package.utils.Util.getRange(Util.java:26)
at com.app.package.DriverActivity.scanDone(SampleActivity.java:982)
at com.app.package.DriverActivity.access$1300(SampleActivity.java:126)
at com.app.package.DriverActivity$11.onScanned(SampleActivity.java:913)
at com.appchannel.bluetooth.BHelper$1.run(BHelper.java:67)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6317)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
I got this log from Crashlytics. I am not able to reproduce this issue on my device.

Depending on what your locale is set to, the character between the integral part and the fractional part of the decimal number can be either ., ,, or something else that I'm not aware of.
DecimalFormat automatically uses the character that corresponds to your locale, so that's why it formats to things like 5,2 instead of 5.2.
However, valueOf does not take locales into account. It looks for . as the separator. So by putting 5,2in there,valueOf` can't recognise it.
To force the decimal format to format so that the result is compatible with valueOf, try to create the DecimalFormat with this:
new DecimalFormat("#.##", DecimalFormatSymbols.getInstance(Locale.US));
EDIT:
I saw that you convert the float back to a string again and return it. Why don't you just return the return value of format?
return decimalFormat.format(len);

5,2is not double or float value ,so you should filter error value ! tosetting textview inputtype !

no need to use decimal format.
yourfloat*=100f;
yourfloat = Math.round(yourfloat);
yourfloat = yourfloat/100f;

Related

Prevent numbers from changing according to the locale in android

When the user change the locale in device the numbers are also getting changed according to the selected locale. This is causing NumberFormatException while performing mathematical operations and app is getting crashed. The code snippet which is causing the crash is given below.
public static double ToDataUnitMB(double _dataBytes){
double dDataBytes;
dDataBytes = Double.parseDouble(getDecimalFormat().format(_dataBytes / 1048576));
return dDataBytes; }
This code snippet is causing NumberFormatException and the value in _dataBytes is shown as "७२.४१". Can anyone help me to prevent the number from changing when user change the locale.
Update
I am getting the value "७२.४१" after performing the below operation getDecimalFormat().format(_dataBytes / 1048576)
So while parsing to Double it is showing numberFormatException
Since you're starting with raw _dataBytes you have several options how to format number independent of the locale.
First Approach:
You can modify following snippet to your needs. It will give you the same output regardless of the user locale.
String patern = "###.##"; //your pattern as per need
Locale locale = new Locale("en", "US");
DecimalFormat decimalFormat = (DecimalFormat) NumberFormat.getNumberInstance(locale);
decimalFormat.applyPattern(patern);
double formatedDouble = Double.parseDouble(decimalFormat.format(_dataBytes/(1024*1024f)));
Keep in mind that this method also makes grouping and decimal separators to be fixed, so that comma and dot will alway be used as, respectively, grouping separator and decimal separator.
Second Approach:
If you do not strictly require Double you could generate formatted String with something similar to following method:
String generateFormatedFileSize(long _dataBytes) {
String formatedFileSize = "";
long bytes = _dataBytes;
short unit = 1024;
if (bytes < unit)
formatedFileSize = bytes + " B";
else {
int exp = (int) (Math.log(bytes) / Math.log(unit));
formatedFileSize = String.format("%.1f %sB", bytes / Math.pow(unit, exp), "KMGT".charAt(exp - 1));
}
return formatedFileSize;
}
This formatting will be sensitive to grouping separator and decimal separator, but otherwise insensitive to Locale.
For Local that uses "US" numbering format, this will give you following output:
12.5 KB
5.3 B
8.0 MB
And for Local using "European" numbering format:
12,5 KB
5,3 B
8,0 MB
Off course, these two methods are not exclusive and you could use some mix of these approaches at different parts of the App.

java.lang.NumberFormatException: Invalid double

I have a method to calculate Difference between two Latitude:
public static double distanceKM(LatLng latLng1, LatLng latLng2) {
int EARTH_RADIUS_KM = 6371;
double lat1Rad = Math.toRadians(latLng1.latitude);
double lat2Rad = Math.toRadians(latLng2.latitude);
double deltaLonRad = Math.toRadians(latLng2.longitude - latLng1.longitude);
double dist_travelled = Math
.acos(Math.sin(lat1Rad) * Math.sin(lat2Rad) + Math.cos(lat1Rad)
* Math.cos(lat2Rad) * Math.cos(deltaLonRad))
* EARTH_RADIUS_KM;
dist_travelled = Double.parseDouble(new DecimalFormat("##.######")
.format(dist_travelled));
return dist_travelled;
}
Sometimes, this method throw Exception (I say sometimes, when I test in defference device):
java.lang.NumberFormatException: Invalid double: "0,179927"
at java.lang.StringToReal.invalidReal(StringToReal.java:63)
at java.lang.StringToReal.parseDouble(StringToReal.java:269)
Can someone help me in this case? Thanks
The value of the double depends on the language of the device. For example, for devices in french the number 0.179927 becomes 0,179927 which will always throw a NumberFormatException when parsing it to double because of the comma.
You need to change the separator from a comma to a point.
You can change the separator either by setting a locale or using the DecimalFormatSymbols.
If you want the grouping separator to be a point, you can use a european locale:
NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMAN);
DecimalFormat df = (DecimalFormat)nf;
Alternatively you can use the DecimalFormatSymbols class to change the symbols that appear in the formatted numbers produced by the format method. These symbols include the decimal separator, the grouping separator, the minus sign, and the percent sign, among others:
DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols(currentLocale);
otherSymbols.setDecimalSeparator(',');
otherSymbols.setGroupingSeparator('.');
DecimalFormat df = new DecimalFormat(formatString, otherSymbols);

unable to get the 2 values after decimals but getting zero

Hi friends I want to get two values after decimal,but in my I am getting 0 after the decimal. this is my code below.
if (!ed.getText().toString().equals("")) {
if (rb1.isChecked()) {
int input = Integer.valueOf(ed.getText().toString());
double out = input / 24;
out = (double)Math.round(out * 100)/100;
Intent m = new Intent(Page.this,MActivity.class);
m.putDoubleExtra("res", out);
startActivity(m);
I referred these sites also: Android : How to get just two digit after the point in decimal value ? dont want to trunc the value
Java : how do I get the part after the decimal point?
and I tried the code below also but it getting 0 after decimal.
DecimalFormat newFormat = new DecimalFormat("#.##");
double twoDecimal = Double.valueOf(newFormat.format(d))
Please help me new to coding. Thanks in advance.
Since input and 24 are integers, when you divide it, it still produces int. Only then it is converted to double.
One way to solve this: double out = input / 24.0;
DecimalFormat newFormat = new DecimalFormat("#.00");
double twoDecimal = Double.valueOf(newFormat.format(d))
In your code i found is
out = (double)Math.round(out * 100.0)/100.0;

Is language conditional in some operations?

I'm developing an app where I use the Geocoder to get a place's coordinates.
The operative is this:
The user defines an address.
The geocoder finds that address and I get the coordinates from that address.
This coordinates are in decimal format and I need them in degrees-minutos so I format them.
To format the coordinates from decimal to degrees-minutes I use:
String frmtLatitude = Location.convert(Double.parseDouble(lat), Location.FORMAT_MINUTES);
So, if I have for example this latitude 43.249591 in decimal value, it returns it like this 43:14.97546.
After this, I have to make some operations to finally get the latitude with this appearance: 4314.975
When I do this operations, one of them is to split the value using the ".". I split 14.97546 to get in one hand the 14 and in the other 97546.
Until here, everything ok. It works fine when I have my phone's language selected to be in english. But if I select to be in spanish, the app crashes. I have followed the stacktrace and it points there. Is like that in english when using the first commented function to convert from decimal to degrees-minutes it separates the decimals with a "." but if I have it in spanish, it separates them with a ",".
Can this really happen or the cause could be another thing?
We can look at the source code of the convert method
public static String convert(double coordinate, int outputType) {
if (coordinate < -180.0 || coordinate > 180.0 ||
Double.isNaN(coordinate)) {
throw new IllegalArgumentException("coordinate=" + coordinate);
}
if ((outputType != FORMAT_DEGREES) &&
(outputType != FORMAT_MINUTES) &&
(outputType != FORMAT_SECONDS)) {
throw new IllegalArgumentException("outputType=" + outputType);
}
StringBuilder sb = new StringBuilder();
// Handle negative values
if (coordinate < 0) {
sb.append('-');
coordinate = -coordinate;
}
DecimalFormat df = new DecimalFormat("###.#####");
if (outputType == FORMAT_MINUTES || outputType == FORMAT_SECONDS) {
int degrees = (int) Math.floor(coordinate);
sb.append(degrees);
sb.append(':');
coordinate -= degrees;
coordinate *= 60.0;
if (outputType == FORMAT_SECONDS) {
int minutes = (int) Math.floor(coordinate);
sb.append(minutes);
sb.append(':');
coordinate -= minutes;
coordinate *= 60.0;
}
}
sb.append(df.format(coordinate));
return sb.toString();
}
We can see that it uses a DecimalFormat with a given pattern. So, if we look to the DecimalFormat constructor :
public DecimalFormat(String pattern) {
// Always applyPattern after the symbols are set
this.symbols = new DecimalFormatSymbols(Locale.getDefault());
applyPattern(pattern, false);
}
We can see here that even if we give a pattern, it uses the locale values. The javadoc also said :
Parameters:
pattern A non-localized pattern string.
To finish, we can go here to see the different local variant of numbers representation : http://docs.oracle.com/cd/E19455-01/806-0169/overview-9/index.html
So we can see that US-English use the "dot format" and that Spanish use "comma format".
To answer your question : the proflem you're facing is probably due to the Decimal format of your locale. I advice you to be REALLY CAREFUL when converting types of objects to make manipulation on them. Converting an int to a String should be only to display it.
I think you should seperate decimal part of your number when it stills a float (or any decimal type) and then convert your object to a String to display it. You can take a look at Math class or search SO to get some example on how to this ;)
Also, as #Dmitry said, you can get DecimalSeparator with DecimalFormatSymbols.getDecimalSeparator().
Sources
Location.convert(double,int) source code
DecimalFormat(String) source code
Java "Decimal and thousands separators"
You are right, decimal seperator depends on your locale. You can get it by something like this
DecimalFormat df = new DecimalFormat();
DecimalFormatSymbols formatSymbols = df.getDecimalFormatSymbols();
char separator = formatSymbols.getDecimalSeparator();

DecimalFormat("#0.000") doesn't format the right way like 1.321 instead of this it delievers 1,321

I want to get a Double with 3 decimalplaces. I do this:
String sAveragePrice;
Double dAveragePrice = holePrice/(allPrices.size()); // delivers 1.3210004
DecimalFormat threeZeroes = new DecimalFormat("#0.000");
sAveragePrice = threeZeroes.format(dAveragePrice); // delivers then 1,321
After formatting I dont get a 1.321 but 1,321. And the 1,321 throws a NumberformatException later. This is when it is thrown:
Double priceInt = Double.parseDouble(sAveragePrice); // throws NumberFormatException
The strange thing is, I have this code till 3 weeks and it didn't make any problem. But today when I have started my app again it gets problem with it. But I didn't have changed anything.
Can anybody help me? I also tried this:
NumberFormat format = NumberFormat.getNumberInstance();
format.setMinimumFractionDigits(3);
format.setMaximumFractionDigits(3);
sAveragePrice = format.format(dAveragePrice);
But it also delivers me a "," instead of a "." for double.
Try using a locale for you number format.
Number format = NumberFormat.getNumberInstance(Locale.ITALIAN);
Java SDK has a limited number of predefined locale settings, so for other locales (e.g., for Russian), you can use the following snippet:
Number format = NumberFormat.getNumberInstance(new Locale("ru", "RU"));
Number format = NumberFormat.getNumberInstance(new Locale("it", "IT")); // etc...
this sample code may help you...
Locale locale = Locale.getDefault();
// set Locale.US as default
Locale.setDefault(Locale.US);
DecimalFormat decimalFormat = new DecimalFormat("##.000");
double d = 14.5589634d;
String format = decimalFormat.format(d);
System.out.println(format);// prints 14.559
// back to default locale
Locale.setDefault(locale);
Have a look at this SO question
How to change the decimal separator of DecimalFormat from comma to dot/point?
Basically your output will be Locale specific, so if you have a Locale of Frame then it will be different to a Locale of the US.
try
NumberFormat format = NumberFormat.getNumberInstance(Locale.US);
Use this type of formatting
use # instead of 0. It is the correct format to declare your pattern
String sAveragePrice;
Double dAveragePrice = holePrice/(allPrices.size());
DecimalFormat threeZeroes = new DecimalFormat("#.###");
sAveragePrice = threeZeroes.format(dAveragePrice);
Hope it will help you

Categories

Resources