Java Decimalformat 과학 표기법 질문
-
06-07-2019 - |
문제
나는 Java를 사용하고 있습니다 십진법 과학 표기법으로 숫자를 인쇄하는 클래스. 그러나 내가 가진 한 가지 문제가 있습니다. 나는 값에 관계없이 고정 길이가 되려면 문자열이 필요하며, 10의 힘의 표시가 그것을 버리고 있습니다. 현재 이것은 내 형식의 모습입니다.
DecimalFormat format = new DecimalFormat("0.0E0");
이것은 다음과 같은 조합을 제공합니다 : 1.0E1, 1.0E -1, -1.0E1 및 -1.0E -1.
나는 사용할 수있다 setpositiveprefix 얻기 : +1.0e1, +1.0e -1, -1.0e1 및 -1.0e -1 또는 내가 좋아하는 것은 전력의 부호에 영향을 미치지 않습니다!
고정 길이 문자열을 가질 수 있도록이를 수행하는 방법이 있습니까? 감사!
편집 : 아, 그래서 Java의 기존을 사용하여 할 수있는 방법이 없습니다. 십진법 API? 제안 해주셔서 감사합니다! 나는 서브 클래스가 필요하다고 생각합니다 십진법 이미 제자리에있는 인터페이스에 의해 제한되어 있기 때문입니다.
해결책
여기에 한 가지 방법이 있습니다. 아마도 호키, 아마도 효과가 있습니다 ...
public class DecimalFormatTest extends TestCase {
private static class MyFormat extends NumberFormat {
private final DecimalFormat decimal;
public MyFormat(String pattern) {
decimal = new DecimalFormat(pattern);
}
public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {
StringBuffer sb = new StringBuffer();
sb.append(modified(Math.abs(number) > 1.0, decimal.format(number, toAppendTo, pos).toString()));
return sb;
}
private String modified(boolean large, String s) {
return large ? s.replace("E", "E+") : s;
}
public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) {
StringBuffer sb = new StringBuffer();
sb.append(modified(true, decimal.format(number, toAppendTo, pos).toString()));
return sb;
}
public Number parse(String source, ParsePosition parsePosition) {
return decimal.parse(source, parsePosition);
}
public void setPositivePrefix(String newValue) {
decimal.setPositivePrefix(newValue);
}
}
private MyFormat format;
protected void setUp() throws Exception {
format = new MyFormat("0.0E0");
format.setPositivePrefix("+");
}
public void testPositiveLargeNumber() throws Exception {
assertEquals("+1.0E+2", format.format(100.0));
}
public void testPositiveSmallNumber() throws Exception {
assertEquals("+1.0E-2", format.format(0.01));
}
public void testNegativeLargeNumber() throws Exception {
assertEquals("-1.0E+2", format.format(-100.0));
}
public void testNegativeSmallNumber() throws Exception {
assertEquals("-1.0E-2", format.format(-0.01));
}
}
또는 당신은 할 수 있습니다 아강 Decimalformat이지만 일반적으로 콘크리트 클래스에서 서브 클래스를 사용하지 않는 것이 더 깨끗합니다.
다른 팁
이것은 나를 형성했습니다.
DecimalFormatSymbols SYMBOLS = DecimalFormatSymbols.getInstance(Locale.US);
if (value > 1 || value < -1) {
SYMBOLS.setExponentSeparator("e+");
} else {
SYMBOLS.setExponentSeparator("e");
}
DecimalFormat format = new DecimalFormat(sb.toString(), SYMBOLS);
당신은 사용할 수 있습니까? printf()
대신에:
Format format = new DecimalFormat("0.0E0");
Double d = new Double(.01);
System.out.println(format.format(d));
System.out.printf("%1.1E\n", d);
d = new Double(100);
System.out.println(format.format(d));
System.out.printf("%1.1E\n", d);
산출:
1.0E-2
1.0E-02
1.0E2
1.0E+02
a에 출력 해야하는 경우 String
대신 제공된 정보를 사용할 수 있습니다 Java (Sprintf)의 형식 인쇄 하기 위해서.
편집 : 와우 PrintfFormat()
물건은 거대하고 불필요한 것 같습니다.
OutputStream b = new ByteArrayOutputStream();
PrintStream p = new PrintStream(b);
p.printf("%1.1E", d);
System.out.println(b.toString());
위의 코드에 대한 아이디어를 얻었습니다 출력 스트림을 문자열로 가져옵니다.
사용하는 방법?
보다 formatTest
방법.
if (value.compareTo(positive) == 1 || value.compareTo(negative) == -1)
매우 많은 숫자에 유용합니다
/**
* inspired by:<br>
* https://stackoverflow.com/a/13065493/8356718
* https://stackoverflow.com/a/18027214/8356718
* https://stackoverflow.com/a/25794946/8356718
*/
public static String format(String number, int scale) {
BigDecimal value = new BigDecimal(number);
DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(Locale.US);
BigDecimal positive = new BigDecimal(1);// scale is zero
positive.setScale(0);// unnecessary
BigDecimal negative = new BigDecimal(-1);// scale is zero
negative.setScale(0);// unnecessary
if (value.compareTo(positive) == 1 || value.compareTo(negative) == -1) {
symbols.setExponentSeparator("e+");
} else {
symbols.setExponentSeparator("e");
}
DecimalFormat formatter = new DecimalFormat("0.0E0", symbols);
formatter.setRoundingMode(RoundingMode.HALF_UP);
formatter.setMinimumFractionDigits(scale);
return formatter.format(value);
}
/**
* set the scale automatically
*/
public static String format(String number) {
BigDecimal value = new BigDecimal(number);
return format(number, value.scale() > 0 ? value.precision() : value.scale());
}
/*
output:
----------
0e0
1.0e-2
-1.0e-2
1.234560e-5
-1.234560e-5
1e0
-1e0
3e+0
-3e+0
2e+2
-2e+2
----------
0.0000000000e0
1.0000000000e-2
-1.0000000000e-2
1.2345600000e-5
-1.2345600000e-5
1.0000000000e0
-1.0000000000e0
3.0000000000e+0
-3.0000000000e+0
2.0000000000e+2
-2.0000000000e+2
----------
*/
public static void formatTest() {
System.out.println("----------");
System.out.println(format("0"));
System.out.println(format("0.01"));
System.out.println(format("-0.01"));
System.out.println(format("0.0000123456"));
System.out.println(format("-0.0000123456"));
System.out.println(format("1"));
System.out.println(format("-1"));
System.out.println(format("3"));
System.out.println(format("-3"));
System.out.println(format("200"));
System.out.println(format("-200"));
System.out.println("----------");
System.out.println(format("0", 10));
System.out.println(format("0.01", 10));
System.out.println(format("-0.01", 10));
System.out.println(format("0.0000123456", 10));
System.out.println(format("-0.0000123456", 10));
System.out.println(format("1", 10));
System.out.println(format("-1", 10));
System.out.println(format("3", 10));
System.out.println(format("-3", 10));
System.out.println(format("200", 10));
System.out.println(format("-200", 10));
System.out.println("----------");
}
대신 "0.0e+0"패턴을 사용하지 않는 이유는 무엇입니까? 마지막 0 이전의 플러스 부호에 주목하십시오.