In Java, I am trying to get DecimalFormat to enforce the sign on an exponent sign. When it is positive I need a plus sign to appear. From what I have read this seems like a no brainer, but for myself it always throws up an error. I appreciate that there may be other methods to achieve my goal, but I would like to understand why in this specific method the error is occurring.
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
The error which is thrown up:
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)
I appreciate any insight.
Thanks,
Mark
Easy way:
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);
Outputs 1.23456E+02
for your example.
But I don't believe there's a way to do it from inside the DecimalFormat
pattern. Or at least the javadoc doesn't indicate there is one.
Edit: trashgod brings up a good point. You'd probably want to get positive and negative signs from DecimalFormatSymbols
if you plan on localizing this to different regions.
Edit 2: Andrei pointed out that E
is also a localization variable. Shows what I know about localization.
I would like to extend the solution by j flemm. The "E" and "-" are no constants, they can be set as DecimalFormatSymbols. Therefore the substitutions must respect this:
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()));
}
Result is:
- 1,23457*10^+03
- 5,67000*10^−03
I don't think the '+' character is an accepted character in a pattern (after studying the javadocs). And the pattern for for the exponential part si described as:
Exponent:
E MinimumExponent
MinimumExponent:
0 MinimumExponent(opt)
If you add anything there it will confuse the parser.
I think your only option is to give it the normal pattern (without '+') and then get the String and use regex to add the '+' there.
sresult = formatter.format(result);
sresult = sresult.replaceAll("E([^\\-]+)", "E+$1");
The best option might be extending DecimalFormat and doing this in the overwritten format method
@j flemm's approach is appealing because "Negative exponents are formatted using the localized minus sign, not the prefix and suffix from the pattern."—DecimalFormat
.