Pregunta

I have the following lines of code in my app to round my percentage to a reasonable length;

double percentage = ((double)correct*100)/((double)total);
DecimalFormat df = new DecimalFormat("#.0");
percentage = Double.valueOf(df.format(percentage));

This code works well 99% of the time, but when people from some European countries use this is crashes, giving me a NumberFormatException.

This is because when the DecimalFormat rounds the double 56.7777, it rounds it to 56,8(with a comma), which means that when I try to convert it to a double, a NumberFormatException is thrown.

Is there any way to set a locality to DecimalFormat so that I know it will always round to 56.8 and not 56,8?

¿Fue útil?

Solución 2

The problem is that you specify a custom format with your DecimalFormat and then parse the resulting String using the format specified by the default Locale.

You have several options to solve the problem:

  1. Use the same DecimalFormat object to both format and parse the number.

  2. Use a different rounding algorithm. For example:

    double roundToHundredths(double d) {
        return (int)(d * 100) / 100.0;
    }
    
  3. Store the number as an int in "hundredths". Do your calculations with this int and display it as a decimal.

  4. Use BigDecimal for greater precision.

Note that using a "rounded" number in any further calculations is still tricky since floating point numbers are imprecise. This means that the "rounded" result is not necessarily exact.

Otros consejos

Use the same number format to parse data

percentage = df.parse(df.format(percentage), new ParsePosition(0))

Other solution is to set your own format symbols

DecimalFormat df = new DecimalFormat('#.0', new DecimalFormatSymbols())

I recommend first solution. I tested it on locale that uses comma as decimal separator.

    NumberFormat numberFormat = NumberFormat.getNumberInstance(context.getResources().getConfiguration().locale); // Locale.getDefaultLocale()
    DecimalFormat  decimalFormat = (DecimalFormat)numberFormat;
    char separator =decimalFormat.getDecimalFormatSymbols().getDecimalSeparator();
    decimalFormat.applyPattern("#".concat(Character.toString(separator)).concat("0"));"

You need to get the decimal separator based on the Locale

You can set the currency for a test value, then format and find whether there is a comma or . and handle appropriately if ,

DecimalFormat test = new DecimalFormat("0.00"); test.setCurrency(c);

String testsample = test.format(1.23); char ch = sample.indexOf(".") > 0 ? "." : ",";

convert the decimal to a string and apply this to it

str = str.replaceAll(",","."); // or "\\.", it doesn't matter...

it will turn all , to .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top