Getting invalid double, but the error shows a proper one - android

My application does some basic arithmetic processes and then adds them to a TextView. Because I want them the result be shown up to XX,XX I format my string with %.2f. Now, when I try to retrieve this result and use it in another arithmetic process, it gives me an error of:
java.lang.NumberFormatException: Invalid double: "8,86" (or any number for that matter)
How can I make the second process convert the string from the TextViewwithout getting an error?
process 1
int newProductQuantity = Integer.valueOf(productQuantity.getText().toString());
double newProductPrice = Double.valueOf(productPrice.getText().toString());
double newProductVAT = Double.valueOf(productVat.getText().toString());
double newProductPriceSum = ((newProductPrice + (newProductPrice * (newProductVAT / 100))) * newProductQuantity);
String newProductPriceSumTexta = String.format("%.2f", newProductPriceSum);
productPriceSum.setText(newProductPriceSumTexta);
process 2
double newOrderFinalLastSum = Double.parseDouble(newOrderFinalSum.getText().toString());
double newOrderFinalNewSum = Double.parseDouble(productPriceSum.getText().toString());
double newOrderFinalOmegaSum = newOrderFinalLastSum + newOrderFinalNewSum; //error is here
String newOrderFinalOmegaSumText = String.format("%.2f", newOrderFinalOmegaSum);
newOrderFinalSum.setText(newOrderFinalOmegaSumText);

your issue is Locale related. If you want always a dot . as separator, you should specify a Locale that use it. You can use format method that takes as first parameter a Locale object. For instance
String.format(Locale.UK,...
From the documentation of public static String format(Locale l, String format, Object... args)
Returns a formatted string using the specified locale, format string,
and arguments.
where
l - The locale to apply during formatting. If l is null then no
localization is applied.

Related

Need to round off two points after decimal digit

I'm working on an app and facing an issue. I've tried a number of solutions but nothing solved my problem.
I need to round off two digits after decimal point.
For Example.
9.225 should be rounded off to 9.23
Thank you.
For Kotlin use "%.2f".format(number), for Java use String.format("%.2f", number)
Result:
You can use String.format("%.2f", d), this will rounded automatically. d is your value.
OR
You can use this
double d = 1.234567;
DecimalFormat df = new DecimalFormat("#.##");
Log.d(df.format(d));
You can get as a float value as well like below.
float value = Float.valueOf(df.format(d)); // Output will be 1.24
I would have gone with a probable over the top solution however this is what i came up with.
It uses regex to split the string value of the number passed and then rounds up/down depending on the leading digit after the decimal place. It will return a Double in the instance but you can change that if you like. It does throw IllegalArgumentException, but thats taste dependant.
/**
* #param value the value that is being transformed
* #param decimalPlace the decimal place you want to return to
* #return transformed value to the decimal place
* #throws IllegalArgumentException
*/
Double roundNumber(#NonNull Double value, #NonNull Integer decimalPlace) throws IllegalArgumentException {
String valueString = value.toString();
if(valueString.length()> decimalPlace+1){
throw new IllegalArgumentException(String.format("The string value of %s is not long enough to have %dplaces", valueString, decimalPlace));
}
Pattern pattern = Pattern.compile("(\\d)('.')(\\d)");
Matcher matcher = pattern.matcher(valueString);
if (matcher.groupCount() != 4) { //0 = entire pattern, so 4 should be the total ?
throw new IllegalArgumentException(String.format("The string value of %s does not contain three groups.", valueString));
}
String decimal = matcher.group(3);
int place = decimal.charAt(decimalPlace);
int afterDecimalPlace = decimal.charAt(decimalPlace + 1);
String newDecimal = decimal.substring(0, decimalPlace - 1);
newDecimal += afterDecimalPlace > 5 ? (place + 1) : place;
return Double.parseDouble(matcher.group(1) + "." + newDecimal);
}

How to use decimal numer (Double data type) as placeholder in String resource

I want to use a more than 1 data type inside a placeholder within a String resource but whenever I try to use a demical number as a numerical value, an error is returned.
Kotlin
val currentLocale = Locale.getDefault()
val distanceWalked = 5.2
val numberFormatter: NumberFormat
val amountOut: String
numberFormatter = NumberFormat.getNumberInstance(currentLocale)
amountOut = numberFormatter.format(distanceWalked)
tv.txt = getString(R.string.distance_decimalnumber_placeholder,amountOut,"*")
Stirng resouce
<string name="distance_decimalnumber_placeholder">You have walked %1$d%2$s metres</string>
Expected result
You have walked 5.2* metres
Error
java.util.IllegalFormatConversionException: d != java.lang.Double
Wrong argument type for formatting argument '#1' in distance_decimalnumber_placeholder: conversion is 'd', received String (argument #2 in method call)
First mistake d is for ints
The problem:
You aready converted to string at: amountOut = numberFormatter.format(distanceWalked) you need to replace with string now
Solution: You don`t need to use $f you need to use $s
tv.txt = getString(R.string.distance_decimalnumber_placeholder,amountOut /* this is a string also*/ ,"*")
<string name="distance_decimalnumber_placeholder">You have walked %1$s%2$s metres</string>
I would like to mention two things :
Don't use d for double ... d is treated as int so use f instead of d. So don't use this
<string name="distance_decimalnumber_placeholder">You have walked %1$d%2$s metres</string>
And You don't need a chartype specifier to display * use * after the f like this
<string name="distance_decimalnumber_placeholder">You have walked %1$f* metres</string>
Notice that I have added only one place holder.

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.

change format of double like ***.***,**

I have double amount. Let amount to be 500000.12. I want to set value of the amount to TextView like this format 500,000.12 (where 12 is cents , 500,000 is dollars).
I wrote this function and it works
private String getAmountAsString(double amount) {
double integralPart = amount % 1;
int fractionalPart = (int) (amount - integralPart);
int integral = (int) integralPart * 100;
String strFractional = String.format("%,d", fractionalPart);
String strAmount = (strFractional + "." + String.valueOf(integral));
return strAmount;
}
But I think that there can be some easy and good way of doing this with java native functions. Can anybody help to find functions or some better way?
various Locale can be used to format float, double etc. You can use:
String.format(Locale.<Your Locale>, "%1$,.2f", myDouble);
Here .2f represents how many digits you want after decimal. If you are not specifying any locale it will use the default locale.
In String class this method is overloaded as:
format(String format, Object... args)
&
format(Locale l, String format, Object... args)
For more info have a look: Link1 , Link2 and Link3
Therefore NumberFormats are used. They are good to handle local differents for different countries.
//define a local, gets automated if a point or comma is correct in this Country.
NumberFormat anotherFormat = NumberFormat.getNumberInstance(Locale.US);
DecimalFormat anotherDFormat = (DecimalFormat) anotherFormat;
anotherDFormat.applyPattern("#.00");//set the number of digits afer the point
anotherDFormat.setGroupingUsed(true);// set grouping
anotherDFormat.setGroupingSize(3);//and size of grouping
double myDouble = 123456.78;
String numberWithSeparators = anotherDFormat.format(myDouble);//convert it
I think you have to take a look at this one
http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html

Convert String to Double excluding part of the string

How to convert double to a string value that I get from the spinner, for example: "10 (ton)."
In summary:
How to convert string to double and delete the part (ton)?
I need only the value 10
Another option is using Java's substring method in the String class.
The signature is:
substring(int beginIndex, int endIndex)
Where endIndex equals to the index of the last character you want to include + 1.
In the case of your example, it will look like this:
String myString = "10 (ton)";
Double dbl = Double.parseDouble(myString.substring(0, 2));
Here is the link to the method:
Java substring
You must parse this String. Here is some example. Also use search.
Check these methods Double.parseDouble() and Double.toString() use these functions for converting double to string or vice-versa.
first you have to get rid of "(ton)" which can be achieved by using a String method for example
String inputString = "10 (ton)";
String str = inputString.split(" ")[0];
After that just parse the double Value
Double dbl = Double.parseDouble(str);
BTW: Not sure whether you want to go from double to string or vice-versa
i have a similar problem.
for correct formatting EditText text content to double value i use this code:
try {
String eAm = etAmount.getText().toString();
DecimalFormat dF = new DecimalFormat("0.00");
Number num = dF.parse(eAm);
mPayContext.amount = num.doubleValue();
} catch (Exception e) {
mPayContext.amount = 0.0d;
}
this is independet from current phone locale and return correct double value.
hope it's help;

Categories

Resources