Runda a Podwójna do 2 miejsc po przecinku [duplikat]
To pytanie ma już odpowiedź tutaj:
- Jak zaokrąglać liczbę do n miejsc po przecinku w Javie 29 odpowiedzi
Jeśli wartość wynosi 200.3456
, należy ją sformatować na 200.34
.
Jeśli jest 200
, to powinno być 200.00
.
13 answers
Oto narzędzie, które zaokrągla (zamiast obcinając) podwójną do określonej liczby miejsc po przecinku.
Na przykład:
round(200.3456, 2); // returns 200.35
Wersja Oryginalna; uważaj z tym
public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
long factor = (long) Math.pow(10, places);
value = value * factor;
long tmp = Math.round(value);
return (double) tmp / factor;
}
To rozkłada się źle w przypadkach narożnych z bardzo dużą liczbą miejsc po przecinku (np. round(1000.0d, 17)
) lub dużą liczbą całkowitą (np. round(90080070060.1d, 9)
). Dzięki Sloinowi za zwrócenie na to uwagi.
Używam powyższego do zaokrąglania "nie-zbyt-duży" podwaja się do 2 lub 3 miejsc po przecinku szczęśliwie przez lata (na przykład, aby oczyścić czas w sekundach dla celów logowania: 27.987654321987 -> 27.99). Ale myślę, że najlepiej tego unikać, ponieważ bardziej niezawodne sposoby są łatwo dostępne, z czystszym kodem też.
Więc użyj tego zamiast
(zaadaptowane z tej odpowiedzi Louisa Wassermana i tej Sean Owen .)
public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}
Zauważ, że HALF_UP
jest trybem zaokrąglania "powszechnie nauczanym w szkole". Peruse dokumentacja RoundingMode , jeśli podejrzewasz, że potrzebujesz czegoś innego, takiego jak zaokrąglenie .
Oczywiście, jeśli wolisz, możesz umieścić powyższe w jednej linii:new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue()
I w każdym przypadku
Zawsze pamiętaj, że reprezentacje zmiennoprzecinkowe za pomocą float
i double
są inexact.
Na przykład rozważmy te wyrażenia:
999199.1231231235 == 999199.1231231236 // true
1.03 - 0.41 // 0.6200000000000001
Dla dokładności, chcesz użyć BigDecimal. I podczas gdy w to, użyj konstruktora, który bierze ciąg, nigdy ten, który bierze podwójnie. Na przykład, spróbuj wykonać to:
System.out.println(new BigDecimal(1.03).subtract(new BigDecimal(0.41)));
System.out.println(new BigDecimal("1.03").subtract(new BigDecimal("0.41")));
Kilka doskonałych dalszych lektur na ten temat:
- W 2004 roku, w ramach projektu "Java-Java", w ramach projektu " java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java-Java]}
- Co Każdy Programista Powinien Wiedzieć O Arytmetyce Zmiennoprzecinkowej]}
If you wanted String formatowanie zamiast (lub dodatkowo do) ściśle zaokrąglanie liczb, zobacz inne odpowiedzi.
Zwróć szczególną uwagę, że round(200, 0)
zwraca 200.0
. Jeśli chcesz wydrukować "200.00", należy najpierw zaokrąglić, a następnie sformatować wynik dla wyjścia (co jest doskonale wyjaśnione w odpowiedź Jespera ).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:59
Jeśli chcesz wydrukować double
z dwoma cyframi po przecinku, użyj czegoś takiego:
double value = 200.3456;
System.out.printf("Value: %.2f", value);
Jeśli chcesz mieć wynik w String
zamiast być drukowanym na konsoli, użyj String.format()
z tymi samymi argumentami:
String result = String.format("%.2f", value);
Lub użyj klasy DecimalFormat
:
DecimalFormat df = new DecimalFormat("####0.00");
System.out.println("Value: " + df.format(value));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-11 07:04:30
Myślę, że tak jest łatwiej:
double time = 200.3456;
DecimalFormat df = new DecimalFormat("#.##");
time = Double.valueOf(df.format(time));
System.out.println(time); // 200.35
Zauważ, że to rzeczywiście będzie zaokrąglanie za Ciebie, a nie tylko formatowanie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-16 00:28:59
Najłatwiej byłoby zrobić taki trik;
double val = ....;
val = val*100;
val = Math.round(val);
val = val /100;
Jeśli val zaczyna się od 200.3456, to idzie do 20034.56, a następnie zaokrągla się do 20035, a następnie dzielimy go na 200.34.
Jeśli chcesz zawsze zaokrąglać w dół, zawsze możemy obciąć, rzucając do int:
double val = ....;
val = val*100;
val = (double)((int) val);
val = val /100;
Ta technika będzie działać w większości przypadków, ponieważ dla bardzo dużych podwójnych (dodatnich lub ujemnych) może przepełnić. ale jeśli wiesz, że twoje wartości będą w odpowiednim zakresie, to powinno działać dla Ciebie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-08 14:48:08
Proszę użyć Apache commons math :
Precision.round(10.4567, 2)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-15 14:46:04
function Double round2(Double val) {
return new BigDecimal(val.toString()).setScale(2,RoundingMode.HALF_UP).doubleValue();
}
Zwróć uwagę na ToString ()!!!!
To dlatego, że BigDecimal konwertuje dokładną binarną formę sobowtóra!!!Są to różne sugerowane metody i ich przypadki niepowodzenia.
// Always Good!
new BigDecimal(val.toString()).setScale(2,RoundingMode.HALF_UP).doubleValue()
Double val = 260.775d; //EXPECTED 260.78
260.77 - WRONG - new BigDecimal(val).setScale(2,RoundingMode.HALF_UP).doubleValue()
Double val = 260.775d; //EXPECTED 260.78
260.77 - TRY AGAIN - Math.round(val * 100.d) / 100.0d
Double val = 256.025d; //EXPECTED 256.03d
256.02 - OOPS - new DecimalFormat("0.00").format(val)
// By default use half even, works if you change mode to half_up
Double val = 256.025d; //EXPECTED 256.03d
256.02 - FAIL - (int)(val * 100 + 0.5) / 100.0;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-19 22:48:33
double value= 200.3456;
DecimalFormat df = new DecimalFormat("0.00");
System.out.println(df.format(value));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-12 13:13:30
Jeśli naprawdę chcesz to samo podwójne, ale zaokrąglone w sposób, w jaki chcesz, możesz użyć BigDecimal, na przykład
new BigDecimal(myValue).setScale(2, RoundingMode.HALF_UP).doubleValue();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-24 18:10:51
double d = 28786.079999999998;
String str = String.format("%1.2f", d);
d = Double.valueOf(str);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-18 12:18:40
Zaokrąglanie sobowtóra zazwyczaj nie jest tym, czego się chce. Zamiast tego użyj String.format()
reprezentowanie go w pożądanym formacie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-11 06:38:54
Dla dwóch zaokrąglonych cyfr. Bardzo proste i w zasadzie aktualizujesz zmienną, a nie tylko wyświetlasz cele, które robi DecimalFormat.
x = Math.floor(x * 100) / 100;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-18 19:59:12
value = (int)(value * 100 + 0.5) / 100.0;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-13 14:19:50
W twoim pytaniu, wydaje się, że chcesz uniknąć zaokrąglania liczb, jak również? Tak myślę .format() będzie zaokrąglać liczby za pomocą half-up, afaik?
więc jeśli chcesz zaokrąglać, 200.3456 powinno być 200.35 dla dokładności 2. ale w Twoim przypadku, jeśli chcesz tylko pierwsze 2, a następnie odrzucić resztę?
Można go pomnożyć przez 100, a następnie rzucić do int (lub biorąc głos liczby), przed podzieleniem przez 100 ponownie.
200.3456 * 100 = 20034.56;
(int) 20034.56 = 20034;
20034/100.0 = 200.34;
Możesz mieć problemy z naprawdę naprawdę dużym liczby zbliżone do granicy. W takim przypadku konwersja na łańcuch i podłańcuch działa równie łatwo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-09 18:54:14