Odpowiedzi:
Możesz użyć printf()
z %f
:
double dexp = 12345678;
System.out.printf("dexp: %f\n", dexp);
To zostanie wydrukowane dexp: 12345678.000000
. Jeśli nie chcesz części ułamkowej, użyj
System.out.printf("dexp: %.0f\n", dexp);
Używa to języka specyfikatora formatu wyjaśnionego w dokumentacji .
Domyślny toString()
format użyty w oryginalnym kodzie został zapisany tutaj .
%.0f
.
%.0f
zaokrągla liczbę. Czy istnieje sposób, aby po prostu odrzucić końcowe zera?
Pięć różnych sposobów konwersji podwójnej liczby na normalną:
import java.math.BigDecimal;
import java.text.DecimalFormat;
public class Runner {
public static void main(String[] args) {
double myvalue = 0.00000021d;
//Option 1 Print bare double.
System.out.println(myvalue);
//Option2, use decimalFormat.
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(8);
System.out.println(df.format(myvalue));
//Option 3, use printf.
System.out.printf("%.9f", myvalue);
System.out.println();
//Option 4, convert toBigDecimal and ask for toPlainString().
System.out.print(new BigDecimal(myvalue).toPlainString());
System.out.println();
//Option 5, String.format
System.out.println(String.format("%.12f", myvalue));
}
}
Ten program drukuje:
2.1E-7
.00000021
0.000000210
0.000000210000000000000001085015324114868562332958390470594167709350585
0.000000210000
Które mają tę samą wartość.
Protip: Jeśli jesteś zdezorientowany, dlaczego te losowe cyfry pojawiają się powyżej pewnego progu w podwójnej wartości, ten film wyjaśnia: komputerowy, dlaczego 0.1
+ 0.2
równa się 0.30000000000001
?
W skrócie:
Jeśli chcesz pozbyć się zer i problemów z ustawieniami regionalnymi, powinieneś użyć:
double myValue = 0.00000021d;
DecimalFormat df = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
df.setMaximumFractionDigits(340); // 340 = DecimalFormat.DOUBLE_FRACTION_DIGITS
System.out.println(df.format(myValue)); // Output: 0.00000021
Wyjaśnienie:
Dlaczego inne odpowiedzi mi nie pasują:
Double.toString()
lub System.out.println
lub FloatingDecimal.toJavaFormatString
wykorzystuje notacji naukowej, gdy podwójne jest mniejsza niż 10 ^ -3 lub większą niż lub równą 10 ^ 7Przy użyciu %f
domyślna dokładność dziesiętna wynosi 6, w przeciwnym razie możesz ją zakodować na stałe, ale powoduje to dodanie dodatkowych zer, jeśli masz mniej miejsc po przecinku. Przykład:
double myValue = 0.00000021d;
String.format("%.12f", myvalue); // Output: 0.000000210000
Używając setMaximumFractionDigits(0);
lub %.0f
usuwasz dokładność dziesiętną, co jest dobre dla liczb całkowitych / długich, ale nie dla podwójnej:
double myValue = 0.00000021d;
System.out.println(String.format("%.0f", myvalue)); // Output: 0
DecimalFormat df = new DecimalFormat("0");
System.out.println(df.format(myValue)); // Output: 0
Korzystając z DecimalFormat, jesteś zależny lokalnie. W języku francuskim separatorem dziesiętnym jest przecinek, a nie kropka:
double myValue = 0.00000021d;
DecimalFormat df = new DecimalFormat("0");
df.setMaximumFractionDigits(340);
System.out.println(df.format(myvalue)); // Output: 0,00000021
Korzystanie z ustawień regionalnych w języku ANGIELSKIM zapewnia, że otrzymasz punkt separatora dziesiętnego, niezależnie od miejsca działania programu.
Po co więc używać 340 setMaximumFractionDigits
?
Dwa powody:
setMaximumFractionDigits
akceptuje liczbę całkowitą, ale jej implementacja ma maksymalną dozwoloną liczbę cyfr, z DecimalFormat.DOUBLE_FRACTION_DIGITS
czego 340Double.MIN_VALUE = 4.9E-324
więc z 340 cyframi na pewno nie zaokrąglisz swojej liczby podwójnej i stracisz precyzję.new BigDecimal(myvalue).toPlainString()
Z opisu na docs.oracle.com/javase/7/docs/api/java/math/… ), nie jest od razu oczywiste, jak się zachowuje, gdy podaje się różne typy liczb, ale eliminuje notację naukową .
new BigDecimal(0.00000021d).toPlainString()
wyjście, 0.0000002100000000000000010850153241148685623329583904705941677093505859375
które nie jest tym, czego można oczekiwać ...
BigDecimal.valueOf(0.00000021d).toPlainString()
również działa (używa konstruktora ciągów BigDecimal, dlatego)
Możesz tego spróbować DecimalFormat
. Dzięki tej klasie możesz bardzo elastycznie analizować swoje liczby.
Możesz dokładnie ustawić wzór, którego chcesz użyć.
W twoim przypadku na przykład:
double test = 12345678;
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(0);
System.out.println(df.format(test)); //12345678
Mam inne rozwiązanie z funkcją toPlainString () BigDecimal, ale tym razem za pomocą konstruktora ciągów, który jest zalecany w javadoc:
ten konstruktor jest zgodny z wartościami zwracanymi przez Float.toString i Double.toString. Jest to ogólnie preferowany sposób konwersji liczby zmiennoprzecinkowej lub podwójnej na BigDecimal, ponieważ nie cierpi z powodu nieprzewidywalności (podwójnego) konstruktora BigDecimal.
Wygląda to tak w najkrótszej formie:
return new BigDecimal(myDouble.toString()).stripTrailingZeros().toPlainString();
W wersjach wcześniejszych niż Java 8 wynikiem tego jest „0.0” dla dowolnych Doubles o zerowej wartości, dlatego należy dodać:
if (myDouble.doubleValue() == 0)
return "0";
NaN i wartości nieskończone należy dodatkowo sprawdzić.
Ostateczny wynik wszystkich tych rozważań:
public static String doubleToString(Double d) {
if (d == null)
return null;
if (d.isNaN() || d.isInfinite())
return d.toString();
// Pre Java 8, a value of 0 would yield "0.0" below
if (d.doubleValue() == 0)
return "0";
return new BigDecimal(d.toString()).stripTrailingZeros().toPlainString();
}
Można to również skopiować / wkleić, aby ładnie współpracować z Float.
d.doubleValue() == 0
zamiast d == 0
?
Musiałem przekonwertować niektóre wartości podwójne na walutę i stwierdziłem, że większość rozwiązań była OK, ale nie dla mnie.
W DecimalFormat
końcu był dla mnie sposób, więc oto co zrobiłem:
public String foo(double value) //Got here 6.743240136E7 or something..
{
DecimalFormat formatter;
if(value - (int)value > 0.0)
formatter = new DecimalFormat("0.00"); // Here you can also deal with rounding if you wish..
else
formatter = new DecimalFormat("0");
return formatter.format(value);
}
Jak widać, jeśli liczba jest naturalna, otrzymuję - powiedzmy - 20000000 zamiast 2E7 (itd.) - bez kropki dziesiętnej.
A jeśli jest dziesiętny, dostaję tylko dwie cyfry dziesiętne.
Kompilator Java / Kotlin konwertuje dowolną wartość większą niż 9999999 (większą lub równą 10 milionom) na notację naukową, tj. Notacja Epsilion .
Np .: 12345678 jest konwertowany na 1,2345678E7
Użyj tego kodu, aby uniknąć automatycznej konwersji na notację naukową:
fun setTotalSalesValue(String total) {
var valueWithoutEpsilon = total.toBigDecimal()
/* Set the converted value to your android text view using setText() function */
salesTextView.setText( valueWithoutEpsilon.toPlainString() )
}
Poniższy kod wykrywa, czy podany numer jest prezentowany w notacji naukowej. Jeśli tak, jest reprezentowany w normalnej prezentacji z maksymalnie 25 cyframi.
static String convertFromScientificNotation(double number) {
// Check if in scientific notation
if (String.valueOf(number).toLowerCase().contains("e")) {
System.out.println("The scientific notation number'"
+ number
+ "' detected, it will be converted to normal representation with 25 maximum fraction digits.");
NumberFormat formatter = new DecimalFormat();
formatter.setMaximumFractionDigits(25);
return formatter.format(number);
} else
return String.valueOf(number);
}
Myślę, że każdy miał dobry pomysł, ale wszystkie odpowiedzi nie były proste. Widzę, że jest to bardzo przydatny fragment kodu. Oto fragment tego, co zadziała:
System.out.println(String.format("%.8f", EnterYourDoubleVariableHere));
".8"
miejscu można ustawić liczbę miejsc po przecinku chcesz pokazać.
Używam Eclipse i to nie działało bez problemu.
Mam nadzieję, że to było pomocne. Byłbym wdzięczny za wszelkie opinie!
Miałem ten sam problem w kodzie produkcyjnym, gdy używałem go jako wejściowego ciągu znaków do funkcji math.Eval (), która pobiera ciąg taki jak „x + 20/50”
Przejrzałem setki artykułów ... W końcu poszedłem z tym ze względu na szybkość. A ponieważ funkcja Eval zamierzała ostatecznie przekonwertować ją z powrotem na własny format liczb, a funkcja mat.Eval () nie obsługiwała końcowego E-07, który zwróciły inne metody, a wszystko powyżej 5 dp było zbyt szczegółowe dla mojej aplikacji .
Jest to teraz używane w kodzie produkcyjnym aplikacji, która ma ponad 1000 użytkowników ...
double value = 0.0002111d;
String s = Double.toString(((int)(value * 100000.0d))/100000.0d); // Round to 5 dp
s display as: 0.00021
Może to być styczna .... ale jeśli musisz wprowadzić wartość liczbową jako liczbę całkowitą (która jest zbyt duża, aby być liczbą całkowitą) w serializatorze (JSON itp.), Prawdopodobnie prawdopodobnie potrzebujesz „BigInterger”
Przykład: wartość jest łańcuchem - 7515904334
Musimy przedstawić go w postaci liczbowej w komunikacie Jsona: {„contact_phone”: „800220-3333”, „servicer_id”: 7515904334, „servicer_name”: „SOME CORPORATION”}
Nie możemy go wydrukować lub otrzymamy: {„contact_phone”: „800220-3333”, „servicer_id”: „7515904334”, „servicer_name”: „SOME CORPORATION”}
Dodanie wartości do takiego węzła daje pożądany wynik: BigInteger.valueOf (Long.parseLong (wartość, 10))
Nie jestem pewien, czy to jest naprawdę na ten temat, ale ponieważ to pytanie było moim największym hitem, kiedy szukałem mojego rozwiązania, pomyślałem, że podzielę się tutaj z korzyścią dla innych, okłamuj mnie, którzy źle wyszukują. :RE
W przypadku wartości całkowitych reprezentowanych przez a double
można użyć tego kodu, który jest znacznie szybszy niż inne rozwiązania.
public static String doubleToString(final double d) {
// check for integer, also see https://stackoverflow.com/a/9898613/868941 and
// https://github.com/google/guava/blob/master/guava/src/com/google/common/math/DoubleMath.java
if (isMathematicalInteger(d)) {
return Long.toString((long)d);
} else {
// or use any of the solutions provided by others
return Double.toString(d);
}
}
// Java 8+
public static boolean isMathematicalInteger(final double d) {
return StrictMath.rint(d) == d && Double.isFinite(d);
}
Moje rozwiązanie: String str = String.format ("% .0f", twojaDouble);
dexp: 12345681.000000
która zła wartość. A właściwie po tym chcę wyświetlić ją na mojej stronie internetowej, gdzie jest wyświetlana w ten sposób.1.2345678E7
Czy mimo to mogę ją przechowywać w dowolny12345678
sposób?