Java DecimalFormat在强制使用指数符号时创建错误
在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");
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的一个功能。确保在代码中记录潜在的本地化问题。