String.format()Bug?

时间:2010-11-30 15:22:45

标签: android

以下针对de_DE语言环境在J2SE和Android中给出了不同的结果:

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

在JRE 1.6.0_22中,我按预期得到“0,5”。

使用Android平台2.2,我得到“0,4”

谢谢,罗兰

2 个答案:

答案 0 :(得分:3)

我不会把它称为bug,除非你指出一个规范,说明String.format方法应该采用哪种舍入模式。似乎1.6 JRE使用UP或HALF_UP作为RoundingMode。但是在Android中,使用了HALF_EVEN模式,这似乎也是DecimalFormat的默认模式。这是我用JRE测试上面的代码:

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));
    }
}

似乎语言环境与舍入模式无关。不幸的是,在Android DecimalFormat似乎不支持舍入模式,所以你不能运行相同的代码。

我也有兴趣在JRE 1.5中运行相同的代码(不支持舍入模式的设置),但我的机器中没有合适的环境。

答案 1 :(得分:0)

找到适用于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());

使用double的String表示来实例化BigDecimal似乎很重要,因为如果不这样做,您将获得一些有趣的值。 这是一个例子:

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

- - - - > BigDecimal:0.84999999999999997779553950749686919152736663818359375

如果您现在使用上面的代码,您当然会得到0.8而不是0.9,这是您所期望的。

谢谢,罗兰