Java DecimalFormat在强制使用指数符号时创建错误

Java DecimalFormat在强制使用指数符号时创建错误,java,exponent,decimalformat,Java,Exponent,Decimalformat,在Java中,我尝试使用DecimalFormat在指数符号上强制执行符号。当它是积极的,我需要一个加号出现。从我所读到的,这似乎是一个无脑的,但对我自己来说,它总是抛出一个错误。我理解可能有其他方法来实现我的目标,但我想了解为什么在这个特定的方法中会出现错误 Double result = 123.456; String sresult; //This works NumberFormat formatter = new DecimalFormat("0.00000E00");

在Java中,我尝试使用DecimalFormat在指数符号上强制执行符号。当它是积极的,我需要一个加号出现。从我所读到的,这似乎是一个无脑的,但对我自己来说,它总是抛出一个错误。我理解可能有其他方法来实现我的目标,但我想了解为什么在这个特定的方法中会出现错误

Double result = 123.456;
String sresult;

//This works
NumberFormat formatter = new DecimalFormat("0.00000E00");
        sresult = formatter.format(result); 
        System.out.println(sresult);        //1.23456E02

//This doesn't work
formatter = new DecimalFormat("0.00000E+00"); //Want to enforce the sign to appear
        sresult = formatter.format(result); 
        System.out.println(sresult);        //Expected 1.23456E+02 but error occurs
引发的错误是:

Exception in thread "main" java.lang.IllegalArgumentException: Malformed exponential pattern "0.00000E+00" at java.text.DecimalFormat.applyPattern(Unknown Source) at java.text.DecimalFormat.(Unknown Source) at deccheck.main(deccheck.java:13) 线程“main”java.lang.IllegalArgumentException中的异常: 格式错误的指数模式“0.00000E+00” 位于java.text.DecimalFormat.applyPattern(未知源) 位于java.text.DecimalFormat。(未知源) 位于decheck.main(decheck.java:13) 我很欣赏你的见解。 谢谢 标记

简易方法:

formatter = new DecimalFormat("0.00000E00"); // Want to enforce the sign to appear
sresult = formatter.format(result);
if (!sresult.contains("E-")) { //don't blast a negative sign
    sresult = sresult.replace("E", "E+");
}
System.out.println(sresult);
为您的示例输出
1.23456E+02

但是我不相信有一种方法可以从
DecimalFormat
模式内部实现。或者至少javadoc没有指出有一个

编辑:垃圾神提出了一个很好的观点。如果您计划将其本地化到不同的区域,您可能希望从
十进制符号中获得正负符号


编辑2:安德烈指出,
E
也是一个本地化变量。显示了我对本地化的了解。

我不认为“+”字符是模式中可接受的字符(在研究javadocs之后)。指数部分si的模式描述为:

 Exponent:
         E MinimumExponent
 MinimumExponent:
         0 MinimumExponent(opt)
如果在那里添加任何内容,都会混淆解析器。 我认为您唯一的选择是给它一个普通模式(不带“+”),然后获取字符串并使用正则表达式在那里添加“+”

sresult = formatter.format(result);
sresult = sresult.replaceAll("E([^\\-]+)", "E+$1");

最好的选择可能是扩展DecimalFormat,并使用覆盖格式方法来实现这一点。flemm的方法很有吸引力,因为“负指数的格式是使用本地化的减号,而不是模式中的前缀和后缀。”——。

我想通过以下方式扩展解决方案。“E”和“-”不是常数,可以设置为。因此,替换必须尊重这一点:

public static String hoola(final String s, final DecimalFormatSymbols symbols) {
    String result;
    final String expo = symbols.getExponentSeparator();
    final char minus = symbols.getMinusSign();
    if (!s.contains(expo + minus)) { // don't blast a negative sign
    result = s.replace(expo, expo + '+');
    } else {result=s;}
    return result;
}

/**
 * @param args
 */
public static void main(final String[] args) {
    final DecimalFormat decForm = (DecimalFormat) NumberFormat
            .getInstance(Locale.GERMAN);
    final DecimalFormatSymbols newSymbols = new DecimalFormatSymbols(
            Locale.GERMAN);
    newSymbols.setExponentSeparator("*10^");
    newSymbols.setMinusSign('\u2212');
    decForm.setDecimalFormatSymbols(newSymbols);
    decForm.applyPattern("0.00000E00");
    System.out.println(hoola(decForm.format(1234.567), decForm
            .getDecimalFormatSymbols()));
    System.out.println(hoola(decForm.format(000.00567), decForm
            .getDecimalFormatSymbols()));
}
结果是:

  • 123457*10^+03
  • 567000*10^−03

重新格式化的代码;如果不正确,请还原。在本地化的情况下,还应使用DecimalFormatSymbols.getExponentSeparator()中的E。问题是,如果不检查是否应该在正则表达式中转义它们,你就不能直接使用它们(你需要额外检查它是否是特殊字符)。@Andrei:+1是的,我也忘记了。是的,“坏”模式会破坏这段代码。实现Desired行为的安全方法是为例如实现自己的NumberFormat扩展。我喜欢它。还不如把
+
中的
+
符号也从
十进制符号中拉出来。@j flemm:我想,但是如果我正确解释javadocs,
+
是不能更改的。这一点很好。我也注意到了。这是有意义的,因为
DecimalFormat
不使用
+
。它可能在另一个本地化常量类中。谢谢大家。我感谢所有的评论。我认为javadocs确实提到了使用+符号的能力,但我对这个链接中提供的信息感到困惑:我将实现j flemm建议的简单方法,因为本地化不会影响我。@Mark:这看起来像Apache Harmony的一个功能。确保在代码中记录潜在的本地化问题。