简体   繁体   中英

getting wrong output while using numberFormat.parse(“”) method in java

I have below piece of code:

I am passing value "55.00000000000000" and getting output as 55.00000000000001.

But when i passed "45.00000000000000" and "65.00000000000000" i get output as 45.0 and 65.0.

Can someone please help me to get correct output as 55.0.

NumberFormat numberFormat = NumberFormat.getPercentInstance(Locale.US);
if (numberFormat instanceof DecimalFormat) {
    DecimalFormat df = (DecimalFormat) numberFormat;
    df.setNegativePrefix("(");
    df.setNegativeSuffix("%)");
}
Number numericValue = numberFormat.parse("55.00000000000000%");
numericValue = new Double(numericValue.doubleValue() * 100);
System.out.println(numericValue);

The problem here is that numericValue is mathematically supposed to be 0.55. However, it will be a Double (because numberFormat.parse() can only return a Long or a Double ). And a Double cannot hold the value 0.55 exactly. See this link for a complete explanation of why. The result is that as you do further computations with the inexact value, roundoff errors will occur, which is why the result being printed out is not quite the exact value. (A Double also cannot be exactly 0.45 or 0.65; it just happens that when multiplying by 100, the result rounds to the correct integer.)

When dealing with decimal values such as money or percentages, it's preferable to use BigDecimal . If the NumberFormat is a DecimalFormat , you can set things up so that parse returns a BigDecimal :

if (numberFormat instanceof DecimalFormat) {
    DecimalFormat df = (DecimalFormat) numberFormat;
    df.setNegativePrefix("(");
    df.setNegativeSuffix("%)");
    df.setParseBigDecimal(true);   // ADD THIS LINE
}

Now, when you use numberFormat.parse() , the Number it returns will be a BigDecimal , which is able to hold the exact value 0.55. Now you have to avoid converting it to a double , which will introduce a roundoff error. Instead, you should say something like

Number numericValue = numberFormat.parse("55.00000000000000%");
if (numericValue instanceof BigDecimal) {
    BigDecimal bdNumber = (BigDecimal) numericValue;
    // use BigDecimal operations to multiply by 100, then print or format
    // or whatever you want to do
} else {
    // you're stuck doing things the old way, you might get some 
    // inaccuracy
    numericValue = new Double(numericValue.doubleValue() * 100);
    System.out.println(numericValue);
}

use this line of code

System.out.println(String.format("%.1f", numericValue));

Where format method use to format your data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM