I have a num开发者_开发技巧ber as a string like this: "9.756088256835938E-4" but I only can use a specified number of characters (in this special case 9 char). So I want to have something like this: "9.7561E-4". I already tried to convert the String to a Double and then used the format method to get a less characters but I don't got a correct solution.
The problem is that I need ten exponential output since some numbers are longer than the number of characters I have. If it is possible, the number should be displayed with no ten exponent, if not just use the ten exponent.
Also correct rounding would be good.
And it should work for negative numbers. (minus needs one character!!!)
Is there a format function where I can define the maximum length of the output string? Any ideas?
I'm having trouble findind a single format pattern that will cover all of the cases that you described. But here's a combination of logic that I think works:
public static void main(String[] args) throws Exception {
// 97.560883
System.out.println(formatNum(Double.parseDouble("9.756088256835938E+1")));
// 9.756E+11
System.out.println(formatNum(Double.parseDouble("9.756088256835938E+11")));
// 0.0009756
System.out.println(formatNum(Double.parseDouble("9.756088256835938E-4")));
// -9.8E+111
System.out.println(formatNum(Double.parseDouble("-9.756088256835938E+111")));
}
private static final int MAX_LENGTH = 9;
private static String formatNum(double number) {
String out = null;
for ( int i = 0; i < MAX_LENGTH; i++ ) {
String format = "%." + i + "G";
out = String.format(format, number);
if ( out.length() == MAX_LENGTH ) {
return out;
}
}
return out; //the best we can do
}
The "G" in the pattern instructs the formatter to forego the use of the exponent when it will allow for the same or better precision. We grow up to the maximum length and stop when our output string is 10 characters. I think you could take the same approach with a DecimalFormat
, but I'm more familiar with Formatter
.
Seeing the Mark's example meet your requirements, I updated my answer to show the DecimalFormat
implementation. I used Mark's test cases. It is definitely an uglier option because there is no easy way to turn on/off exponents. The only advantage over the String.format
option is that it handles very small numbers well.
public static void main(String[] args) throws Exception {
// 97.560883
System.out.println(formatNum(Double.parseDouble("9.756088256835938E+1")));
// 9.756E+11
System.out.println(formatNum(Double.parseDouble("9.756088256835938E+11")));
// 0.0009756
System.out.println(formatNum(Double.parseDouble("9.756088256835938E-4")));
// -9.8E+111
System.out.println(formatNum(Double.parseDouble("-9.756088256835938E+111")));
}
private static final int MAX_LENGTH = 9;
private static String formatNum(double number) {
int digitsAvailable = MAX_LENGTH - 2;
if (Math.abs(number) < Math.pow(10, digitsAvailable)
&& Math.abs(number) > Math.pow(10, -digitsAvailable)) {
String format = "0.";
double temp = number;
for (int i = 0; i < digitsAvailable; i++) {
if ((temp /= 10) < 1) {
format += "#";
}
}
return new DecimalFormat(format).format(number);
}
String format = "0.";
for (int i = 0; i < digitsAvailable; i++) {
format += "#";
}
String r = new DecimalFormat(format + "E0").format(number);
int lastLength = r.length() + 1;
while (r.length() > MAX_LENGTH && lastLength > r.length()) {
lastLength = r.length();
r = r.replaceAll("\\.?[0-9]E", "E");
}
return r;
}
This reminded me of a similar question where the OP only had 5 or so spaces for a number and wanted to show a decimal only when there was enough space. But instead of exponents, wanted to use a suffix of (k,m, etc)
精彩评论