2010-08-06 26 views
2

时在Java中,我试图让DecimalFormat的执行对指数的标志符号产生误差。当它是积极的,我需要一个加号出现。从我读过的这段话看来,这似乎毫无意义,但对我自己来说总是会引发一个错误。我很欣赏可能有其他方法来实现我的目标,但我想了解为什么在这种特定方法中发生错误。的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) 

我明白任何见解。 谢谢, 马克

+0

重新格式化的代码;如果不正确请回复。 – trashgod 2010-08-06 14:49:43

回答

3

简单的方法:

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并没有表明有一个。

编辑: trashgod带来了一个好点。如果您计划将其本地化到不同的地区,您可能需要获得DecimalFormatSymbols的正面和负面信号。

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

+2

在本地化的情况下,E也应该从DecimalFormatSymbols.getExponentSeparator()中使用。这个问题是,你不能直接使用它们,不检查你是否应该在正则表达式中转义它们(你需要额外检查它是否是特殊字符)。 – 2010-08-06 15:52:48

+0

@Andrei:+1是的,我也忘了。 – 2010-08-06 16:18:21

+0

谢谢。那很棒。 – Mark 2010-08-08 22:21:35

1

我不认为'+'字符是模式中接受的字符(在学习javadoc之后)。如果添加任何那里它会混淆分析器

Exponent: 
     E MinimumExponent 
MinimumExponent: 
     0 MinimumExponent(opt) 

:并为指数部分SI模式描述为。 我认为你唯一的选择是给它正常模式(不带'+'),然后得到字符串,并使用正则表达式在那里添加'+'。

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

最好的选择可能会延长的DecimalFormat,并在覆盖格式方法

1

@j flemm的做法,是因为“负指数使用的是本地化的减号,没有前缀和后缀从格式化呼吁这样做该模式。“ - DecimalFormat

+0

谢谢大家。我很欣赏所有的评论。 我以为javadocs确实提到了使用+号的能力,但我对此链接中提供的信息感到困惑: http://www.docjar.com/docs/api/java/text/DecimalFormat.html 我将执行j flemm建议的简单方法,因为本地化不应该影响我。 – Mark 2010-08-08 22:19:25

+0

@Mark:它看起来像Apache Harmony http://harmony.apache.org/的一个特性。请务必记录代码中潜在的本地化问题。 – trashgod 2010-08-08 22:50:02

3

我想通过j flemm来扩展解决方案。 “E”和“ - ”不是常数,它们可以设置为DecimalFormatSymbols。因此,替换必须尊重此:

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

结果是:

  • 1,23457 * 10^+ 03
  • 5,67000 * 10^-03
+0

是的,“坏”模式会破坏这段代码。实现所需行为的安全方法是实现NumberFormat自己的扩展,例如。 – 2010-08-06 16:07:19

+0

我喜欢。也可以从'DecimalFormatSymbols'中拉''hoola(..)'中的'+'符号。 – 2010-08-06 16:12:11

+0

@j flemm:我想要,但是如果我正确解释javadoc,'+'是不可更改的。 – 2010-08-06 16:18:04