开发者

String.format() Bug?

The following gives different results开发者_开发百科 in J2SE and Android for the de_DE locale:

Locale locale = new Locale("de","DE");
log(String.format(locale,"%.1f", 0.45));

In JRE 1.6.0_22, I get "0,5" as expected.

With the Android Platform 2.2 I get "0,4"

Thanks, Roland


I wouldn't call it a bug, unless you point me to a specification that says, which rounding mode the String.format method should be using. It seems that the 1.6 JRE uses UP or HALF_UP as a RoundingMode. In Android however, HALF_EVEN mode is used, which also seems the default mode for DecimalFormat. This is the code I've used with JRE to test the above:

import java.util.Locale;
import java.text.DecimalFormat;
import java.math.RoundingMode;

public class Test {

    public static void main(String [] args) {
        Locale locale = new Locale("de","DE");
        String str = String.format(locale,"%.1f", 0.45);
        System.out.println(str);
        System.out.println(String.format("%.1f", 0.45));

        DecimalFormat df = new DecimalFormat("#.#");
        System.out.println(df.format(0.45));
        System.out.println(df.getRoundingMode());
        df.setRoundingMode(RoundingMode.HALF_UP);
        System.out.println(df.format(0.45));
    }
}

It seems that the locale has nothing to do with the rounding mode. Unfortunately, in Android DecimalFormat doesn't seem to support Rounding Modes, so you can't run the same code as is.

I would also be interested in running the same code in JRE 1.5 (which doesn't support the setting of Rounding Mode), but I don't have a suitable environment in my machine.


Found the solution for Android:

// format 
DecimalFormat df = new DecimalFormat("0.0");
BigDecimal valDec = new BigDecimal(String.valueOf(val));
BigDecimal roundedDec = valDec.setScale(1,BigDecimal.ROUND_HALF_UP);
return df.format(roundedDec.doubleValue());

It's seems to be important to instantiate the BigDecimal with the String representation of the double because if you don't, you will get some funny values. Here's an example:

BigDecimal test = new BigDecimal(0.85);
Log.v(TAG,"BigDecimal: "+test.toPlainString());

-----> BigDecimal: 0.84999999999999997779553950749686919152736663818359375

If you now use the code above, you of course get 0.8 and not 0.9, what you would expect.

Thanks, Roland

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜