What I would like is a method to convert a double to a string which rounds using the half-up method - i.e. if the decimal to be rounded is 5, it always rounds up to the previous number. This is the standard method of rounding most people expect in most situations.
我想要的是一种方法,将double转换为一个字符串,该字符串使用的是半向上的方法,即如果小数部分为5,那么它总是会与之前的数字相匹配。在大多数情况下,这是大多数人所期望的标准方法。
I also would like only significant digits to be displayed - i.e. there should not be any trailing zeroes.
我也希望只显示有效数字,即不应该有任何尾随零。
I know one method of doing this is to use the String.format
method:
我知道一种方法是使用字符串。格式的方法:
String.format("%.5g%n", 0.912385);
returns:
返回:
0.91239
which is great, however it always displays numbers with 5 decimal places even if they are not significant:
这很好,但是它总是显示有5位小数的数字即使它们不重要:
String.format("%.5g%n", 0.912300);
returns:
返回:
0.91230
Another method is to use the DecimalFormatter
:
另一种方法是使用DecimalFormatter:
DecimalFormat df = new DecimalFormat("#.#####");
df.format(0.912385);
returns:
返回:
0.91238
However as you can see this uses half-even rounding. That is it will round down if the previous digit is even. What I'd like is this:
然而,正如你看到的,它使用了一半甚至是四舍五入。如果前面的数字是偶数,它就会圆。我想要的是:
0.912385 -> 0.91239
0.912300 -> 0.9123
What is the best way to achieve this in Java?
在Java中实现这个目标的最好方法是什么?
31 个解决方案
#1
553
Use setRoundingMode
, set the RoundingMode
explicitly to handle your issue with the half-even round, then use the format pattern for your required output.
使用setRoundingMode,明确地设置RoundingMode以处理您的问题,甚至是半圆形,然后使用所需输出的格式模式。
Example:
例子:
DecimalFormat df = new DecimalFormat("#.####");
df.setRoundingMode(RoundingMode.CEILING);
for (Number n : Arrays.asList(12, 123.12345, 0.23, 0.1, 2341234.212431324)) {
Double d = n.doubleValue();
System.out.println(df.format(d));
}
gives the output:
给出了输出:
12
123.1235
0.23
0.1
2341234.2125
#2
391
Assuming value
is a double
, you can do:
假设价值是一倍,你可以这样做:
(double)Math.round(value * 100000d) / 100000d
That's for 5 digits precision. The number of zeros indicate the number of decimals.
这是5位数的精度。0表示小数的个数。
#3
160
new BigDecimal(String.valueOf(double)).setScale(yourScale, BigDecimal.ROUND_HALF_UP);
will get you a BigDecimal
. To get the string out of it, just call that BigDecimal
's toString
method, or the toPlainString
method for Java 5+ for a plain format string.
会得到一个BigDecimal。要想获得字符串,只需调用BigDecimal的toString方法,或者为普通格式字符串使用Java 5+的toPlainString方法。
Sample program:
示例程序:
package trials;
import java.math.BigDecimal;
public class Trials {
public static void main(String[] args) {
int yourScale = 10;
System.out.println(BigDecimal.valueOf(0.42344534534553453453-0.42324534524553453453).setScale(yourScale, BigDecimal.ROUND_HALF_UP));
}
#4
96
You can also use the
你也可以使用。
DecimalFormat df = new DecimalFormat("#.00000");
df.format(0.912385);
to make sure you have the trailing 0's.
要确保你有后面的0。
#5
73
As some others have noted, the correct answer is to use either DecimalFormat
or BigDecimal
. Floating-point doesn't have decimal places so you cannot possibly round/truncate to a specific number of them in the first place. You have to work in a decimal radix, and that is what those two classes do.
正如其他一些人所指出的,正确的答案是使用DecimalFormat或BigDecimal。浮点数没有十进制位,所以您不可能在一开始就将其转换为一个特定的数字。你必须用十进制的基数,这就是这两个类的作用。
I am posting the following code as a counter-example to all the answers in this thread and indeed all over * (and elsewhere) that recommend multiplication followed by truncation followed by division. It is incumbent on advocates of this technique to explain why the following code produces the wrong output in over 92% of cases.
我将下面的代码作为一个反例,作为这个线程中所有答案的一个反例,并且实际上所有的*(以及其他地方)都推荐了乘法,然后是截断,然后是除法。这一技术的倡导者有责任解释为什么以下代码在超过92%的案例中产生了错误的输出。
public class RoundingCounterExample
{
static float roundOff(float x, int position)
{
float a = x;
double temp = Math.pow(10.0, position);
a *= temp;
a = Math.round(a);
return (a / (float)temp);
}
public static void main(String[] args)
{
float a = roundOff(0.0009434f,3);
System.out.println("a="+a+" (a % .001)="+(a % 0.001));
int count = 0, errors = 0;
for (double x = 0.0; x < 1; x += 0.0001)
{
count++;
double d = x;
int scale = 2;
double factor = Math.pow(10, scale);
d = Math.round(d * factor) / factor;
if ((d % 0.01) != 0.0)
{
System.out.println(d + " " + (d % 0.01));
errors++;
}
}
System.out.println(count + " trials " + errors + " errors");
}
}
Output of this program:
这个项目的输出:
10001 trials 9251 errors
EDIT: To address some comments below I redid the modulus part of the test loop using BigDecimal
and new MathContext(16)
for the modulus operation as follows:
编辑:为了解决下面的一些评论,我用BigDecimal和new MathContext(16)重新计算了测试循环的模数部分,如下图所示:
public static void main(String[] args)
{
int count = 0, errors = 0;
int scale = 2;
double factor = Math.pow(10, scale);
MathContext mc = new MathContext(16, RoundingMode.DOWN);
for (double x = 0.0; x < 1; x += 0.0001)
{
count++;
double d = x;
d = Math.round(d * factor) / factor;
BigDecimal bd = new BigDecimal(d, mc);
bd = bd.remainder(new BigDecimal("0.01"), mc);
if (bd.multiply(BigDecimal.valueOf(100)).remainder(BigDecimal.ONE, mc).compareTo(BigDecimal.ZERO) != 0)
{
System.out.println(d + " " + bd);
errors++;
}
}
System.out.println(count + " trials " + errors + " errors");
}
Result:
结果:
10001 trials 4401 errors
#6
70
Suppose you have
假设你有
double d = 9232.129394d;
you can use BigDecimal
您可以使用BigDecimal
BigDecimal bd = new BigDecimal(d).setScale(2, RoundingMode.HALF_EVEN);
d = bd.doubleValue();
or without BigDecimal
或没有BigDecimal
d = Math.round(d*100)/100.0d;
with both solutions d == 9232.13
两个解d == 9232.13。
#7
51
You can use the DecimalFormat class.
您可以使用DecimalFormat类。
double d = 3.76628729;
DecimalFormat newFormat = new DecimalFormat("#.##");
double twoDecimal = Double.valueOf(newFormat.format(d));
#8
34
Real's Java How-to posts this solution, which is also compatible for versions before Java 1.6.
Real的Java howto发布这个解决方案,它也兼容于Java 1.6之前的版本。
BigDecimal bd = new BigDecimal(Double.toString(d));
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
return bd.doubleValue();
#9
30
double myNum = .912385;
int precision = 10000; //keep 4 digits
myNum= Math.floor(myNum * precision +.5)/precision;
#10
26
@Milhous: the decimal format for rounding is excellent:
@Milhous:四舍五入的十进制格式非常好:
You can also use the
你也可以使用。
DecimalFormat df = new DecimalFormat("#.00000"); df.format(0.912385);
to make sure you have the trailing 0's.
要确保你有后面的0。
I would add that this method is very good at providing an actual numeric, rounding mechanism - not only visually, but also when processing.
我要补充的是,这个方法非常擅长提供一个实际的数字,舍入机制——不仅在视觉上,而且在处理过程中。
Hypothetical: you have to implement a rounding mechanism into a GUI program. To alter the accuracy / precision of a result output simply change the caret format (i.e. within the brackets). So that:
假设:您必须将一个舍入机制实现到GUI程序中。为了改变结果输出的精度/精度,只需改变插入符号的格式(即括号内)。这样:
DecimalFormat df = new DecimalFormat("#0.######");
df.format(0.912385);
would return as output: 0.912385
将返回输出:0.912385 ?
DecimalFormat df = new DecimalFormat("#0.#####");
df.format(0.912385);
would return as output: 0.91239
将作为输出返回:0.91239 ?
DecimalFormat df = new DecimalFormat("#0.####");
df.format(0.912385);
would return as output: 0.9124
将作为输出返回:0.9124 ?
[EDIT: also if the caret format is like so ("#0.############") and you enter a decimal, e.g. 3.1415926, for argument's sake, DecimalFormat does not produce any garbage (e.g. trailing zeroes) and will return: 3.1415926
.. if you're that way inclined. Granted, it's a little verbose for the liking of some dev's - but hey, it's got a low memory footprint during processing and is very easy to implement.]
[编辑:如果插入语的格式是这样的(############ ############ ## @ ####### @ ###### @ #### @ # @ # @ # @ # @ # @ # @ # @ # @ ## @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @如果你这样想的话。当然,对某些开发人员的喜好来说,它有点冗长——但是,在处理过程中,它的内存占用率很低,而且很容易实现。
So essentially, the beauty of DecimalFormat is that it simultaneously handles the string appearance - as well as the level of rounding precision set. Ergo: you get two benefits for the price of one code implementation. ;)
因此,从本质上讲,DecimalFormat的优点是它同时处理字符串的外观,以及舍入精度集的级别。,)
#11
17
You could use the following utility method-
你可以使用下面的实用方法。
public static double round(double valueToRound, int numberOfDecimalPlaces)
{
double multipicationFactor = Math.pow(10, numberOfDecimalPlaces);
double interestedInZeroDPs = valueToRound * multipicationFactor;
return Math.round(interestedInZeroDPs) / multipicationFactor;
}
#12
15
Here is a summary of what you can use if you want the result as String:
这里是一个总结,如果您希望结果是字符串:
-
DecimalFormat#setRoundingMode():
DecimalFormat # setRoundingMode():
DecimalFormat df = new DecimalFormat("#.#####"); df.setRoundingMode(RoundingMode.HALF_UP); String str1 = df.format(0.912385)); // 0.91239
-
BigDecimal # setScale()
String str2 = new BigDecimal(0.912385) .setScale(5, BigDecimal.ROUND_HALF_UP) .toString();
Here is a suggestion of what libraries you can use if you want double
as a result. I wouldn't recommend it for string conversion, though, as double may not be able to represent what you want exactly (see e.g. here):
这里有一个建议,如果你想要双重的结果,你可以使用什么库。不过,我不会推荐它用于字符串转换,因为double可能不能准确地表示您想要的内容(参见这里):
#13
8
You can use BigDecimal
您可以使用BigDecimal
BigDecimal value = new BigDecimal("2.3");
value = value.setScale(0, RoundingMode.UP);
BigDecimal value1 = new BigDecimal("-2.3");
value1 = value1.setScale(0, RoundingMode.UP);
System.out.println(value + "n" + value1);
Refer: http://www.javabeat.net/precise-rounding-of-decimals-using-rounding-mode-enumeration/
参见:http://www.javabeat.net/precise-rounding-of-decimals-using-rounding-mode-enumeration/
#14
7
Try this: org.apache.commons.math3.util.Precision.round(double x, int scale)
试试这个:org.apache.common。math3.util. round(double x, int scale)
See: http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/Precision.html
参见:http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/Precision.html
Apache Commons Mathematics Library homepage is: http://commons.apache.org/proper/commons-math/index.html
Apache Commons数学图书馆主页是:http://commons.apache.org/proper/commons-math/index.html。
The internal implemetation of this method is:
该方法的内部实现为:
public static double round(double x, int scale) {
return round(x, scale, BigDecimal.ROUND_HALF_UP);
}
public static double round(double x, int scale, int roundingMethod) {
try {
return (new BigDecimal
(Double.toString(x))
.setScale(scale, roundingMethod))
.doubleValue();
} catch (NumberFormatException ex) {
if (Double.isInfinite(x)) {
return x;
} else {
return Double.NaN;
}
}
}
#15
6
Since I found no complete answer on this theme I've put together a class that should handle this properly, with support for:
由于我在这个主题上没有找到完整的答案,所以我把一个应该正确处理的类放在一起,并支持:
- Formatting: Easily format a double to string with a certain number of decimal places
- 格式化:轻松地格式化一个双到字符串,并有一定数量的小数。
- Parsing: Parse the formatted value back to double
- 解析:将格式化后的值解析为double。
- Locale: Format and parse using the default locale
- 区域:使用默认语言环境的格式和解析。
- Exponential notation: Start using exponential notation after a certain threshold
- 指数符号:在某个阈值后开始使用指数符号。
Usage is pretty simple:
使用非常简单:
(For the sake of this example I am using a custom locale)
(为了这个例子,我使用了一个自定义语言环境)
public static final int DECIMAL_PLACES = 2;
NumberFormatter formatter = new NumberFormatter(DECIMAL_PLACES);
String value = formatter.format(9.319); // "9,32"
String value2 = formatter.format(0.0000005); // "5,00E-7"
String value3 = formatter.format(1324134123); // "1,32E9"
double parsedValue1 = formatter.parse("0,4E-2", 0); // 0.004
double parsedValue2 = formatter.parse("0,002", 0); // 0.002
double parsedValue3 = formatter.parse("3423,12345", 0); // 3423.12345
Here is the class:
这里是类:
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.util.Locale;
public class NumberFormatter {
private static final String SYMBOL_INFINITE = "\u221e";
private static final char SYMBOL_MINUS = '-';
private static final char SYMBOL_ZERO = '0';
private static final int DECIMAL_LEADING_GROUPS = 10;
private static final int EXPONENTIAL_INT_THRESHOLD = 1000000000; // After this value switch to exponential notation
private static final double EXPONENTIAL_DEC_THRESHOLD = 0.0001; // Below this value switch to exponential notation
private DecimalFormat decimalFormat;
private DecimalFormat decimalFormatLong;
private DecimalFormat exponentialFormat;
private char groupSeparator;
public NumberFormatter(int decimalPlaces) {
configureDecimalPlaces(decimalPlaces);
}
public void configureDecimalPlaces(int decimalPlaces) {
if (decimalPlaces <= 0) {
throw new IllegalArgumentException("Invalid decimal places");
}
DecimalFormatSymbols separators = new DecimalFormatSymbols(Locale.getDefault());
separators.setMinusSign(SYMBOL_MINUS);
separators.setZeroDigit(SYMBOL_ZERO);
groupSeparator = separators.getGroupingSeparator();
StringBuilder decimal = new StringBuilder();
StringBuilder exponential = new StringBuilder("0.");
for (int i = 0; i < DECIMAL_LEADING_GROUPS; i++) {
decimal.append("###").append(i == DECIMAL_LEADING_GROUPS - 1 ? "." : ",");
}
for (int i = 0; i < decimalPlaces; i++) {
decimal.append("#");
exponential.append("0");
}
exponential.append("E0");
decimalFormat = new DecimalFormat(decimal.toString(), separators);
decimalFormatLong = new DecimalFormat(decimal.append("####").toString(), separators);
exponentialFormat = new DecimalFormat(exponential.toString(), separators);
decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
decimalFormatLong.setRoundingMode(RoundingMode.HALF_UP);
exponentialFormat.setRoundingMode(RoundingMode.HALF_UP);
}
public String format(double value) {
String result;
if (Double.isNaN(value)) {
result = "";
} else if (Double.isInfinite(value)) {
result = String.valueOf(SYMBOL_INFINITE);
} else {
double absValue = Math.abs(value);
if (absValue >= 1) {
if (absValue >= EXPONENTIAL_INT_THRESHOLD) {
value = Math.floor(value);
result = exponentialFormat.format(value);
} else {
result = decimalFormat.format(value);
}
} else if (absValue < 1 && absValue > 0) {
if (absValue >= EXPONENTIAL_DEC_THRESHOLD) {
result = decimalFormat.format(value);
if (result.equalsIgnoreCase("0")) {
result = decimalFormatLong.format(value);
}
} else {
result = exponentialFormat.format(value);
}
} else {
result = "0";
}
}
return result;
}
public String formatWithoutGroupSeparators(double value) {
return removeGroupSeparators(format(value));
}
public double parse(String value, double defValue) {
try {
return decimalFormat.parse(value).doubleValue();
} catch (ParseException e) {
e.printStackTrace();
}
return defValue;
}
private String removeGroupSeparators(String number) {
return number.replace(String.valueOf(groupSeparator), "");
}
}
#16
6
Here's a basic solution offered by jpdymond:
以下是jpdymond提供的基本解决方案:
public static double round(double value, int precision) {
int scale = (int) Math.pow(10, precision);
return (double) Math.round(value * scale) / scale;
}
https://*.com/a/22186845/212950
https://*.com/a/22186845/212950
#17
5
If you really want decimal numbers for calculation (and not only for output), do not use a binary-based floating point format like double. Use BigDecimal or any other decimal-based format. – Paŭlo Ebermann
如果您真的想要计算的十进制数(而不仅仅是输出),不要使用基于二进制的浮点格式,比如double。使用BigDecimal或任何其他基于十进制的格式。——Paŭlo Ebermann
I do use BigDecimal for calculations, but bear in mind it is dependent on the size of numbers you're dealing with. In most my implementations, i find parsing from double or integer to Long is sufficient enough for very large number calculations. In fact, i've recently used parsed-to-Long to get accurate representations (as opposed to hex results) in a gui for numbers as big as ################################# characters (as an example).
我用BigDecimal来计算,但是记住它取决于你要处理的数字的大小。在大多数我的实现中,我发现从double或integer到Long的解析对于非常大的数字计算来说是足够的。事实上,我最近使用了一段时间来获得准确的表示(而不是十六进制的结果),而在一个图形用户界面中,输入的数字就像一个例子。
#18
5
Just in case someone still needs help with this. This solution works perfectly for me.
以防有人需要帮助。这个解决方案对我来说是完美的。
private String withNoTrailingZeros(final double value, final int nrOfDecimals) {
return new BigDecimal(String.valueOf(value)).setScale(nrOfDecimals, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString();
}
returns a String
with the desired output.
返回一个带有所需输出的字符串。
#19
4
If you're using DecimalFormat
to convert double
to String
, it's very straightforward:
如果使用DecimalFormat将double转换为String,它非常简单:
DecimalFormat formatter = new DecimalFormat("0.0##");
formatter.setRoundingMode(RoundingMode.HALF_UP);
double num = 1.234567;
return formatter.format(num);
There are several RoundingMode
enum values to select from, depending upon the behaviour you require.
根据您所需要的行为,有几个RoundingMode枚举值可供选择。
#20
3
The code snippet below shows how to display n digits. The trick is to set variable pp to 1 followed by n zeros. In the example below, variable pp value has 5 zeros, so 5 digits will be displayed.
下面的代码片段显示了如何显示n个数字。诀窍是将变量pp设置为1,然后是n个零。在下面的示例中,变量pp值有5个零,因此将显示5位数字。
double pp = 10000;
double myVal = 22.268699999999967;
String needVal = "22.2687";
double i = (5.0/pp);
String format = "%10.4f";
String getVal = String.format(format,(Math.round((myVal +i)*pp)/pp)-i).trim();
#21
3
I came here just wanting a simple answer on how to round a number. This is a supplemental answer to provide that.
我来这里只是想要一个简单的答案,关于如何绕过一个数字。这是补充的答案。
How to round a number in Java
The most common case is to use Math.round()
.
最常见的情况是使用Math.round()。
Math.round(3.7) // 4
Numbers are rounded to the nearest whole number. A .5
value is rounded up. If you need different rounding behavior than that, you can use one of the other Math functions. See the comparison below.
数字四舍五入到最接近的整数。一个。5的值被集中。如果你需要不同的舍入行为,你可以使用其他的数学函数。参见下面的比较。
round
As stated above, this rounds to the nearest whole number. .5
decimals round up. This method returns an int
.
如上所述,这轮到最近的整数。该方法返回一个整数。
Math.round(3.0); // 3
Math.round(3.1); // 3
Math.round(3.5); // 4
Math.round(3.9); // 4
Math.round(-3.0); // -3
Math.round(-3.1); // -3
Math.round(-3.5); // -3 *** careful here ***
Math.round(-3.9); // -4
ceil
Any decimal value is rounded up to the next integer. It goes to the ceiling. This method returns a double
.
任何十进制值都被集中到下一个整数。它到了天花板。这个方法返回一个double。
Math.ceil(3.0); // 3.0
Math.ceil(3.1); // 4.0
Math.ceil(3.5); // 4.0
Math.ceil(3.9); // 4.0
Math.ceil(-3.0); // -3.0
Math.ceil(-3.1); // -3.0
Math.ceil(-3.5); // -3.0
Math.ceil(-3.9); // -3.0
floor
Any decimal value is rounded down to the next integer. This method returns a double
.
任何十进制值都被舍去到下一个整数。这个方法返回一个double。
Math.floor(3.0); // 3.0
Math.floor(3.1); // 3.0
Math.floor(3.5); // 3.0
Math.floor(3.9); // 3.0
Math.floor(-3.0); // -3.0
Math.floor(-3.1); // -4.0
Math.floor(-3.5); // -4.0
Math.floor(-3.9); // -4.0
rint
This is similar to round in that decimal values round to the closest integer. However, unlike round
, .5
values round to the even integer. This method returns a double
.
这类似于把十进制值四舍五入到最接近的整数。然而,不像圆,.5的值圆到偶数。这个方法返回一个double。
Math.rint(3.0); // 3.0
Math.rint(3.1); // 3.0
Math.rint(3.5); // 4.0 ***
Math.rint(3.9); // 4.0
Math.rint(4.5); // 4.0 ***
Math.rint(5.5); // 6.0 ***
Math.rint(-3.0); // -3.0
Math.rint(-3.1); // -3.0
Math.rint(-3.5); // -4.0 ***
Math.rint(-3.9); // -4.0
Math.rint(-4.5); // -4.0 ***
Math.rint(-5.5); // -6.0 ***
#22
3
I agree with the chosen answer to use DecimalFormat
--- or alternatively BigDecimal
.
我同意使用DecimalFormat——或者是BigDecimal——的选择答案。
Please read Update below first!
请先阅读以下更新!
However if you do want to round the double value and get a double
value result, you can use org.apache.commons.math3.util.Precision.round(..)
as mentioned above. The implementation uses BigDecimal
, is slow and creates garbage.
但是,如果您想要绕过double值并得到一个双值结果,您可以使用org.apache.common .math3.util. precision.round (..)这个实现使用了BigDecimal,它是缓慢的,并且创建了垃圾。
A similar but fast and garbage-free method is provided by the DoubleRounder
utility in the decimal4j library:
在decimal4j库中,DoubleRounder实用程序提供了一个类似但快速且不含垃圾的方法:
double a = DoubleRounder.round(2.0/3.0, 3);
double b = DoubleRounder.round(2.0/3.0, 3, RoundingMode.DOWN);
double c = DoubleRounder.round(1000.0d, 17);
double d = DoubleRounder.round(90080070060.1d, 9);
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
Will output
将输出
0.667
0.666
1000.0
9.00800700601E10
See https://github.com/tools4j/decimal4j/wiki/DoubleRounder-Utility
参见https://github.com/tools4j/decimal4j/wiki/DoubleRounder-Utility
Disclaimer: I am involved in the decimal4j project.
免责声明:我参与了decimal4j项目。
Update: As @iaforek pointed out DoubleRounder sometimes returns counterintuitive results. The reason is that it performs mathematically correct rounding. For instance DoubleRounder.round(256.025d, 2)
will be rounded down to 256.02 because the double value represented as 256.025d is somewhat smaller than the rational value 256.025 and hence will be rounded down.
更新:@iaforek指出DoubleRounder有时会返回违反直觉的结果。原因是它在数学上正确的四舍五入。例如,DoubleRounder.round(256.025d, 2)将被四舍五入到256.02,因为被表示为256.025d的双值比rational值256.025要小一些,因此会被舍入。
Notes:
注:
- This behaviour is very similar to that of the
BigDecimal(double)
constructor (but not tovalueOf(double)
which uses the string constructor). - 这种行为非常类似于BigDecimal(double)构造函数(而不是使用字符串构造函数的valueOf(double))。
- The problem can be circumvented with a double rounding step to a higher precision first, but it is complicated and I am not going into the details here
- 这个问题可以用一个双圆的步骤来解决,但它是复杂的,我不打算详细讲。
For those reasons and everything mentioned above in this post I cannot recommend to use DoubleRounder.
由于上述原因和上述内容,我不建议使用DoubleRounder。
#23
2
DecimalFormat is the best ways to output, but I don't prefer it. I always do this all the time, because it return the double value. So I can use it more than just output.
DecimalFormat是输出的最好方法,但我不喜欢它。我总是这样做,因为它返回了双重值。所以我可以用它不仅仅是输出。
Math.round(selfEvaluate*100000d.0)/100000d.0;
OR
或
Math.round(selfEvaluate*100000d.0)*0.00000d1;
If you need large decimal places value, you can use BigDecimal instead. Anyways .0
is important. Without it the rounding of 0.33333d5 return 0.33333 and only 9 digits are allows. The second function without .0
has problems with 0.30000 return 0.30000000000000004.
如果需要大的小数位数,可以使用BigDecimal。不管怎样。0是很重要的。没有它,0。33333d5返回0。33333,只有9个数字是允许的。第二个函数没有。0有0。30000返回0.30000000000000004的问题。
#24
1
Where dp = decimal place you want, and value is a double.
在这里,dp =小数点后,值为2。
double p = Math.pow(10d, dp);
double result = Math.round(value * p)/p;
#25
1
Keep in mind that String.format() and DecimalFormat produce string using default Locale. So they may write formatted number with dot or comma as a separator between integer and decimal parts. To make sure that rounded String is in the format you want use java.text.NumberFormat as so:
请记住,string .format()和DecimalFormat使用默认语言环境生成字符串。因此,他们可以用点或逗号作为整数和小数部分之间的分隔符。要确保圆型字符串是您想要使用java.text的格式。NumberFormat所以:
Locale locale = Locale.ENGLISH;
NumberFormat nf = NumberFormat.getNumberInstance(locale);
// for trailing zeros:
nf.setMinimumFractionDigits(2);
// round to 2 digits:
nf.setMaximumFractionDigits(2);
System.out.println(nf.format(.99));
System.out.println(nf.format(123.567));
System.out.println(nf.format(123.0));
Will print in English locale (no matter what your locale is): 0.99 123.57 123.00
将打印在英语地区(无论您的地区是什么):0.99123.57 123.00 ?
The example is taken from Farenda - how to convert double to String correctly.
这个例子来自Farenda——如何正确地将double转换为字符串。
#26
1
If you Consider 5 or n number of decimal. May be this answer solve your prob.
如果你考虑5或n位数的小数。也许这个答案可以解决你的问题。
double a = 123.00449;
double roundOff1 = Math.round(a*10000)/10000.00;
double roundOff2 = Math.round(roundOff1*1000)/1000.00;
double roundOff = Math.round(roundOff2*100)/100.00;
System.out.println("result:"+roundOff);
Output will be: 123.01
this can be solve with loop and recursive function.
输出将是:123.01这可以用循环和递归函数来解决。
#27
1
DecimalFormat myFormatter = new DecimalFormat("0.000");
String output = myFormatter.format(2.34d);
#28
1
If you're using a technology that has a minimal JDK. Here's a way without any Java libs:
如果您使用的是一个具有最小JDK的技术。这里有一个没有任何Java libs的方法:
double scale = 100000;
double myVal = 0.912385;
double rounded = (int)((myVal * scale) + 0.5d) / scale;
#29
1
To achieve this we can use this formatter:
为了达到这个目的,我们可以使用这个格式化程序:
DecimalFormat df = new DecimalFormat("#.00");
String resultado = df.format(valor)
or:
或者:
DecimalFormat df = new DecimalFormat("0.00"); :
Use this method to get always two decimals:
用这个方法得到两个小数:
private static String getTwoDecimals(double value){
DecimalFormat df = new DecimalFormat("0.00");
return df.format(value);
}
Defining this values:
定义这个值:
91.32
5.22
11.5
1.2
2.6
Using the method we can get this results:
使用这个方法我们可以得到这个结果:
91.32
5.22
11.50
1.20
2.60
在线演示。
#30
0
In general, rounding is done by scaling: round(num / p) * p
一般来说,四舍五入是通过缩放来完成的:圆形(num / p) * p。
/**
* MidpointRounding away from zero ('arithmetic' rounding)
* Uses a half-epsilon for correction. (This offsets IEEE-754
* half-to-even rounding that was applied at the edge cases).
*/
double RoundCorrect(double num, int precision) {
double c = 0.5 * EPSILON * num;
// double p = Math.pow(10, precision); //slow
double p = 1; while (precision--> 0) p *= 10;
if (num < 0)
p *= -1;
return Math.round((num + c) * p) / p;
}
// testing edge cases
RoundCorrect(1.005, 2); // 1.01 correct
RoundCorrect(2.175, 2); // 2.18 correct
RoundCorrect(5.015, 2); // 5.02 correct
RoundCorrect(-1.005, 2); // -1.01 correct
RoundCorrect(-2.175, 2); // -2.18 correct
RoundCorrect(-5.015, 2); // -5.02 correct
#1
553
Use setRoundingMode
, set the RoundingMode
explicitly to handle your issue with the half-even round, then use the format pattern for your required output.
使用setRoundingMode,明确地设置RoundingMode以处理您的问题,甚至是半圆形,然后使用所需输出的格式模式。
Example:
例子:
DecimalFormat df = new DecimalFormat("#.####");
df.setRoundingMode(RoundingMode.CEILING);
for (Number n : Arrays.asList(12, 123.12345, 0.23, 0.1, 2341234.212431324)) {
Double d = n.doubleValue();
System.out.println(df.format(d));
}
gives the output:
给出了输出:
12
123.1235
0.23
0.1
2341234.2125
#2
391
Assuming value
is a double
, you can do:
假设价值是一倍,你可以这样做:
(double)Math.round(value * 100000d) / 100000d
That's for 5 digits precision. The number of zeros indicate the number of decimals.
这是5位数的精度。0表示小数的个数。
#3
160
new BigDecimal(String.valueOf(double)).setScale(yourScale, BigDecimal.ROUND_HALF_UP);
will get you a BigDecimal
. To get the string out of it, just call that BigDecimal
's toString
method, or the toPlainString
method for Java 5+ for a plain format string.
会得到一个BigDecimal。要想获得字符串,只需调用BigDecimal的toString方法,或者为普通格式字符串使用Java 5+的toPlainString方法。
Sample program:
示例程序:
package trials;
import java.math.BigDecimal;
public class Trials {
public static void main(String[] args) {
int yourScale = 10;
System.out.println(BigDecimal.valueOf(0.42344534534553453453-0.42324534524553453453).setScale(yourScale, BigDecimal.ROUND_HALF_UP));
}
#4
96
You can also use the
你也可以使用。
DecimalFormat df = new DecimalFormat("#.00000");
df.format(0.912385);
to make sure you have the trailing 0's.
要确保你有后面的0。
#5
73
As some others have noted, the correct answer is to use either DecimalFormat
or BigDecimal
. Floating-point doesn't have decimal places so you cannot possibly round/truncate to a specific number of them in the first place. You have to work in a decimal radix, and that is what those two classes do.
正如其他一些人所指出的,正确的答案是使用DecimalFormat或BigDecimal。浮点数没有十进制位,所以您不可能在一开始就将其转换为一个特定的数字。你必须用十进制的基数,这就是这两个类的作用。
I am posting the following code as a counter-example to all the answers in this thread and indeed all over * (and elsewhere) that recommend multiplication followed by truncation followed by division. It is incumbent on advocates of this technique to explain why the following code produces the wrong output in over 92% of cases.
我将下面的代码作为一个反例,作为这个线程中所有答案的一个反例,并且实际上所有的*(以及其他地方)都推荐了乘法,然后是截断,然后是除法。这一技术的倡导者有责任解释为什么以下代码在超过92%的案例中产生了错误的输出。
public class RoundingCounterExample
{
static float roundOff(float x, int position)
{
float a = x;
double temp = Math.pow(10.0, position);
a *= temp;
a = Math.round(a);
return (a / (float)temp);
}
public static void main(String[] args)
{
float a = roundOff(0.0009434f,3);
System.out.println("a="+a+" (a % .001)="+(a % 0.001));
int count = 0, errors = 0;
for (double x = 0.0; x < 1; x += 0.0001)
{
count++;
double d = x;
int scale = 2;
double factor = Math.pow(10, scale);
d = Math.round(d * factor) / factor;
if ((d % 0.01) != 0.0)
{
System.out.println(d + " " + (d % 0.01));
errors++;
}
}
System.out.println(count + " trials " + errors + " errors");
}
}
Output of this program:
这个项目的输出:
10001 trials 9251 errors
EDIT: To address some comments below I redid the modulus part of the test loop using BigDecimal
and new MathContext(16)
for the modulus operation as follows:
编辑:为了解决下面的一些评论,我用BigDecimal和new MathContext(16)重新计算了测试循环的模数部分,如下图所示:
public static void main(String[] args)
{
int count = 0, errors = 0;
int scale = 2;
double factor = Math.pow(10, scale);
MathContext mc = new MathContext(16, RoundingMode.DOWN);
for (double x = 0.0; x < 1; x += 0.0001)
{
count++;
double d = x;
d = Math.round(d * factor) / factor;
BigDecimal bd = new BigDecimal(d, mc);
bd = bd.remainder(new BigDecimal("0.01"), mc);
if (bd.multiply(BigDecimal.valueOf(100)).remainder(BigDecimal.ONE, mc).compareTo(BigDecimal.ZERO) != 0)
{
System.out.println(d + " " + bd);
errors++;
}
}
System.out.println(count + " trials " + errors + " errors");
}
Result:
结果:
10001 trials 4401 errors
#6
70
Suppose you have
假设你有
double d = 9232.129394d;
you can use BigDecimal
您可以使用BigDecimal
BigDecimal bd = new BigDecimal(d).setScale(2, RoundingMode.HALF_EVEN);
d = bd.doubleValue();
or without BigDecimal
或没有BigDecimal
d = Math.round(d*100)/100.0d;
with both solutions d == 9232.13
两个解d == 9232.13。
#7
51
You can use the DecimalFormat class.
您可以使用DecimalFormat类。
double d = 3.76628729;
DecimalFormat newFormat = new DecimalFormat("#.##");
double twoDecimal = Double.valueOf(newFormat.format(d));
#8
34
Real's Java How-to posts this solution, which is also compatible for versions before Java 1.6.
Real的Java howto发布这个解决方案,它也兼容于Java 1.6之前的版本。
BigDecimal bd = new BigDecimal(Double.toString(d));
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
return bd.doubleValue();
#9
30
double myNum = .912385;
int precision = 10000; //keep 4 digits
myNum= Math.floor(myNum * precision +.5)/precision;
#10
26
@Milhous: the decimal format for rounding is excellent:
@Milhous:四舍五入的十进制格式非常好:
You can also use the
你也可以使用。
DecimalFormat df = new DecimalFormat("#.00000"); df.format(0.912385);
to make sure you have the trailing 0's.
要确保你有后面的0。
I would add that this method is very good at providing an actual numeric, rounding mechanism - not only visually, but also when processing.
我要补充的是,这个方法非常擅长提供一个实际的数字,舍入机制——不仅在视觉上,而且在处理过程中。
Hypothetical: you have to implement a rounding mechanism into a GUI program. To alter the accuracy / precision of a result output simply change the caret format (i.e. within the brackets). So that:
假设:您必须将一个舍入机制实现到GUI程序中。为了改变结果输出的精度/精度,只需改变插入符号的格式(即括号内)。这样:
DecimalFormat df = new DecimalFormat("#0.######");
df.format(0.912385);
would return as output: 0.912385
将返回输出:0.912385 ?
DecimalFormat df = new DecimalFormat("#0.#####");
df.format(0.912385);
would return as output: 0.91239
将作为输出返回:0.91239 ?
DecimalFormat df = new DecimalFormat("#0.####");
df.format(0.912385);
would return as output: 0.9124
将作为输出返回:0.9124 ?
[EDIT: also if the caret format is like so ("#0.############") and you enter a decimal, e.g. 3.1415926, for argument's sake, DecimalFormat does not produce any garbage (e.g. trailing zeroes) and will return: 3.1415926
.. if you're that way inclined. Granted, it's a little verbose for the liking of some dev's - but hey, it's got a low memory footprint during processing and is very easy to implement.]
[编辑:如果插入语的格式是这样的(############ ############ ## @ ####### @ ###### @ #### @ # @ # @ # @ # @ # @ # @ # @ # @ ## @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @ # @如果你这样想的话。当然,对某些开发人员的喜好来说,它有点冗长——但是,在处理过程中,它的内存占用率很低,而且很容易实现。
So essentially, the beauty of DecimalFormat is that it simultaneously handles the string appearance - as well as the level of rounding precision set. Ergo: you get two benefits for the price of one code implementation. ;)
因此,从本质上讲,DecimalFormat的优点是它同时处理字符串的外观,以及舍入精度集的级别。,)
#11
17
You could use the following utility method-
你可以使用下面的实用方法。
public static double round(double valueToRound, int numberOfDecimalPlaces)
{
double multipicationFactor = Math.pow(10, numberOfDecimalPlaces);
double interestedInZeroDPs = valueToRound * multipicationFactor;
return Math.round(interestedInZeroDPs) / multipicationFactor;
}
#12
15
Here is a summary of what you can use if you want the result as String:
这里是一个总结,如果您希望结果是字符串:
-
DecimalFormat#setRoundingMode():
DecimalFormat # setRoundingMode():
DecimalFormat df = new DecimalFormat("#.#####"); df.setRoundingMode(RoundingMode.HALF_UP); String str1 = df.format(0.912385)); // 0.91239
-
BigDecimal # setScale()
String str2 = new BigDecimal(0.912385) .setScale(5, BigDecimal.ROUND_HALF_UP) .toString();
Here is a suggestion of what libraries you can use if you want double
as a result. I wouldn't recommend it for string conversion, though, as double may not be able to represent what you want exactly (see e.g. here):
这里有一个建议,如果你想要双重的结果,你可以使用什么库。不过,我不会推荐它用于字符串转换,因为double可能不能准确地表示您想要的内容(参见这里):
#13
8
You can use BigDecimal
您可以使用BigDecimal
BigDecimal value = new BigDecimal("2.3");
value = value.setScale(0, RoundingMode.UP);
BigDecimal value1 = new BigDecimal("-2.3");
value1 = value1.setScale(0, RoundingMode.UP);
System.out.println(value + "n" + value1);
Refer: http://www.javabeat.net/precise-rounding-of-decimals-using-rounding-mode-enumeration/
参见:http://www.javabeat.net/precise-rounding-of-decimals-using-rounding-mode-enumeration/
#14
7
Try this: org.apache.commons.math3.util.Precision.round(double x, int scale)
试试这个:org.apache.common。math3.util. round(double x, int scale)
See: http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/Precision.html
参见:http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/Precision.html
Apache Commons Mathematics Library homepage is: http://commons.apache.org/proper/commons-math/index.html
Apache Commons数学图书馆主页是:http://commons.apache.org/proper/commons-math/index.html。
The internal implemetation of this method is:
该方法的内部实现为:
public static double round(double x, int scale) {
return round(x, scale, BigDecimal.ROUND_HALF_UP);
}
public static double round(double x, int scale, int roundingMethod) {
try {
return (new BigDecimal
(Double.toString(x))
.setScale(scale, roundingMethod))
.doubleValue();
} catch (NumberFormatException ex) {
if (Double.isInfinite(x)) {
return x;
} else {
return Double.NaN;
}
}
}
#15
6
Since I found no complete answer on this theme I've put together a class that should handle this properly, with support for:
由于我在这个主题上没有找到完整的答案,所以我把一个应该正确处理的类放在一起,并支持:
- Formatting: Easily format a double to string with a certain number of decimal places
- 格式化:轻松地格式化一个双到字符串,并有一定数量的小数。
- Parsing: Parse the formatted value back to double
- 解析:将格式化后的值解析为double。
- Locale: Format and parse using the default locale
- 区域:使用默认语言环境的格式和解析。
- Exponential notation: Start using exponential notation after a certain threshold
- 指数符号:在某个阈值后开始使用指数符号。
Usage is pretty simple:
使用非常简单:
(For the sake of this example I am using a custom locale)
(为了这个例子,我使用了一个自定义语言环境)
public static final int DECIMAL_PLACES = 2;
NumberFormatter formatter = new NumberFormatter(DECIMAL_PLACES);
String value = formatter.format(9.319); // "9,32"
String value2 = formatter.format(0.0000005); // "5,00E-7"
String value3 = formatter.format(1324134123); // "1,32E9"
double parsedValue1 = formatter.parse("0,4E-2", 0); // 0.004
double parsedValue2 = formatter.parse("0,002", 0); // 0.002
double parsedValue3 = formatter.parse("3423,12345", 0); // 3423.12345
Here is the class:
这里是类:
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.util.Locale;
public class NumberFormatter {
private static final String SYMBOL_INFINITE = "\u221e";
private static final char SYMBOL_MINUS = '-';
private static final char SYMBOL_ZERO = '0';
private static final int DECIMAL_LEADING_GROUPS = 10;
private static final int EXPONENTIAL_INT_THRESHOLD = 1000000000; // After this value switch to exponential notation
private static final double EXPONENTIAL_DEC_THRESHOLD = 0.0001; // Below this value switch to exponential notation
private DecimalFormat decimalFormat;
private DecimalFormat decimalFormatLong;
private DecimalFormat exponentialFormat;
private char groupSeparator;
public NumberFormatter(int decimalPlaces) {
configureDecimalPlaces(decimalPlaces);
}
public void configureDecimalPlaces(int decimalPlaces) {
if (decimalPlaces <= 0) {
throw new IllegalArgumentException("Invalid decimal places");
}
DecimalFormatSymbols separators = new DecimalFormatSymbols(Locale.getDefault());
separators.setMinusSign(SYMBOL_MINUS);
separators.setZeroDigit(SYMBOL_ZERO);
groupSeparator = separators.getGroupingSeparator();
StringBuilder decimal = new StringBuilder();
StringBuilder exponential = new StringBuilder("0.");
for (int i = 0; i < DECIMAL_LEADING_GROUPS; i++) {
decimal.append("###").append(i == DECIMAL_LEADING_GROUPS - 1 ? "." : ",");
}
for (int i = 0; i < decimalPlaces; i++) {
decimal.append("#");
exponential.append("0");
}
exponential.append("E0");
decimalFormat = new DecimalFormat(decimal.toString(), separators);
decimalFormatLong = new DecimalFormat(decimal.append("####").toString(), separators);
exponentialFormat = new DecimalFormat(exponential.toString(), separators);
decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
decimalFormatLong.setRoundingMode(RoundingMode.HALF_UP);
exponentialFormat.setRoundingMode(RoundingMode.HALF_UP);
}
public String format(double value) {
String result;
if (Double.isNaN(value)) {
result = "";
} else if (Double.isInfinite(value)) {
result = String.valueOf(SYMBOL_INFINITE);
} else {
double absValue = Math.abs(value);
if (absValue >= 1) {
if (absValue >= EXPONENTIAL_INT_THRESHOLD) {
value = Math.floor(value);
result = exponentialFormat.format(value);
} else {
result = decimalFormat.format(value);
}
} else if (absValue < 1 && absValue > 0) {
if (absValue >= EXPONENTIAL_DEC_THRESHOLD) {
result = decimalFormat.format(value);
if (result.equalsIgnoreCase("0")) {
result = decimalFormatLong.format(value);
}
} else {
result = exponentialFormat.format(value);
}
} else {
result = "0";
}
}
return result;
}
public String formatWithoutGroupSeparators(double value) {
return removeGroupSeparators(format(value));
}
public double parse(String value, double defValue) {
try {
return decimalFormat.parse(value).doubleValue();
} catch (ParseException e) {
e.printStackTrace();
}
return defValue;
}
private String removeGroupSeparators(String number) {
return number.replace(String.valueOf(groupSeparator), "");
}
}
#16
6
Here's a basic solution offered by jpdymond:
以下是jpdymond提供的基本解决方案:
public static double round(double value, int precision) {
int scale = (int) Math.pow(10, precision);
return (double) Math.round(value * scale) / scale;
}
https://*.com/a/22186845/212950
https://*.com/a/22186845/212950
#17
5
If you really want decimal numbers for calculation (and not only for output), do not use a binary-based floating point format like double. Use BigDecimal or any other decimal-based format. – Paŭlo Ebermann
如果您真的想要计算的十进制数(而不仅仅是输出),不要使用基于二进制的浮点格式,比如double。使用BigDecimal或任何其他基于十进制的格式。——Paŭlo Ebermann
I do use BigDecimal for calculations, but bear in mind it is dependent on the size of numbers you're dealing with. In most my implementations, i find parsing from double or integer to Long is sufficient enough for very large number calculations. In fact, i've recently used parsed-to-Long to get accurate representations (as opposed to hex results) in a gui for numbers as big as ################################# characters (as an example).
我用BigDecimal来计算,但是记住它取决于你要处理的数字的大小。在大多数我的实现中,我发现从double或integer到Long的解析对于非常大的数字计算来说是足够的。事实上,我最近使用了一段时间来获得准确的表示(而不是十六进制的结果),而在一个图形用户界面中,输入的数字就像一个例子。
#18
5
Just in case someone still needs help with this. This solution works perfectly for me.
以防有人需要帮助。这个解决方案对我来说是完美的。
private String withNoTrailingZeros(final double value, final int nrOfDecimals) {
return new BigDecimal(String.valueOf(value)).setScale(nrOfDecimals, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString();
}
returns a String
with the desired output.
返回一个带有所需输出的字符串。
#19
4
If you're using DecimalFormat
to convert double
to String
, it's very straightforward:
如果使用DecimalFormat将double转换为String,它非常简单:
DecimalFormat formatter = new DecimalFormat("0.0##");
formatter.setRoundingMode(RoundingMode.HALF_UP);
double num = 1.234567;
return formatter.format(num);
There are several RoundingMode
enum values to select from, depending upon the behaviour you require.
根据您所需要的行为,有几个RoundingMode枚举值可供选择。
#20
3
The code snippet below shows how to display n digits. The trick is to set variable pp to 1 followed by n zeros. In the example below, variable pp value has 5 zeros, so 5 digits will be displayed.
下面的代码片段显示了如何显示n个数字。诀窍是将变量pp设置为1,然后是n个零。在下面的示例中,变量pp值有5个零,因此将显示5位数字。
double pp = 10000;
double myVal = 22.268699999999967;
String needVal = "22.2687";
double i = (5.0/pp);
String format = "%10.4f";
String getVal = String.format(format,(Math.round((myVal +i)*pp)/pp)-i).trim();
#21
3
I came here just wanting a simple answer on how to round a number. This is a supplemental answer to provide that.
我来这里只是想要一个简单的答案,关于如何绕过一个数字。这是补充的答案。
How to round a number in Java
The most common case is to use Math.round()
.
最常见的情况是使用Math.round()。
Math.round(3.7) // 4
Numbers are rounded to the nearest whole number. A .5
value is rounded up. If you need different rounding behavior than that, you can use one of the other Math functions. See the comparison below.
数字四舍五入到最接近的整数。一个。5的值被集中。如果你需要不同的舍入行为,你可以使用其他的数学函数。参见下面的比较。
round
As stated above, this rounds to the nearest whole number. .5
decimals round up. This method returns an int
.
如上所述,这轮到最近的整数。该方法返回一个整数。
Math.round(3.0); // 3
Math.round(3.1); // 3
Math.round(3.5); // 4
Math.round(3.9); // 4
Math.round(-3.0); // -3
Math.round(-3.1); // -3
Math.round(-3.5); // -3 *** careful here ***
Math.round(-3.9); // -4
ceil
Any decimal value is rounded up to the next integer. It goes to the ceiling. This method returns a double
.
任何十进制值都被集中到下一个整数。它到了天花板。这个方法返回一个double。
Math.ceil(3.0); // 3.0
Math.ceil(3.1); // 4.0
Math.ceil(3.5); // 4.0
Math.ceil(3.9); // 4.0
Math.ceil(-3.0); // -3.0
Math.ceil(-3.1); // -3.0
Math.ceil(-3.5); // -3.0
Math.ceil(-3.9); // -3.0
floor
Any decimal value is rounded down to the next integer. This method returns a double
.
任何十进制值都被舍去到下一个整数。这个方法返回一个double。
Math.floor(3.0); // 3.0
Math.floor(3.1); // 3.0
Math.floor(3.5); // 3.0
Math.floor(3.9); // 3.0
Math.floor(-3.0); // -3.0
Math.floor(-3.1); // -4.0
Math.floor(-3.5); // -4.0
Math.floor(-3.9); // -4.0
rint
This is similar to round in that decimal values round to the closest integer. However, unlike round
, .5
values round to the even integer. This method returns a double
.
这类似于把十进制值四舍五入到最接近的整数。然而,不像圆,.5的值圆到偶数。这个方法返回一个double。
Math.rint(3.0); // 3.0
Math.rint(3.1); // 3.0
Math.rint(3.5); // 4.0 ***
Math.rint(3.9); // 4.0
Math.rint(4.5); // 4.0 ***
Math.rint(5.5); // 6.0 ***
Math.rint(-3.0); // -3.0
Math.rint(-3.1); // -3.0
Math.rint(-3.5); // -4.0 ***
Math.rint(-3.9); // -4.0
Math.rint(-4.5); // -4.0 ***
Math.rint(-5.5); // -6.0 ***
#22
3
I agree with the chosen answer to use DecimalFormat
--- or alternatively BigDecimal
.
我同意使用DecimalFormat——或者是BigDecimal——的选择答案。
Please read Update below first!
请先阅读以下更新!
However if you do want to round the double value and get a double
value result, you can use org.apache.commons.math3.util.Precision.round(..)
as mentioned above. The implementation uses BigDecimal
, is slow and creates garbage.
但是,如果您想要绕过double值并得到一个双值结果,您可以使用org.apache.common .math3.util. precision.round (..)这个实现使用了BigDecimal,它是缓慢的,并且创建了垃圾。
A similar but fast and garbage-free method is provided by the DoubleRounder
utility in the decimal4j library:
在decimal4j库中,DoubleRounder实用程序提供了一个类似但快速且不含垃圾的方法:
double a = DoubleRounder.round(2.0/3.0, 3);
double b = DoubleRounder.round(2.0/3.0, 3, RoundingMode.DOWN);
double c = DoubleRounder.round(1000.0d, 17);
double d = DoubleRounder.round(90080070060.1d, 9);
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
Will output
将输出
0.667
0.666
1000.0
9.00800700601E10
See https://github.com/tools4j/decimal4j/wiki/DoubleRounder-Utility
参见https://github.com/tools4j/decimal4j/wiki/DoubleRounder-Utility
Disclaimer: I am involved in the decimal4j project.
免责声明:我参与了decimal4j项目。
Update: As @iaforek pointed out DoubleRounder sometimes returns counterintuitive results. The reason is that it performs mathematically correct rounding. For instance DoubleRounder.round(256.025d, 2)
will be rounded down to 256.02 because the double value represented as 256.025d is somewhat smaller than the rational value 256.025 and hence will be rounded down.
更新:@iaforek指出DoubleRounder有时会返回违反直觉的结果。原因是它在数学上正确的四舍五入。例如,DoubleRounder.round(256.025d, 2)将被四舍五入到256.02,因为被表示为256.025d的双值比rational值256.025要小一些,因此会被舍入。
Notes:
注:
- This behaviour is very similar to that of the
BigDecimal(double)
constructor (but not tovalueOf(double)
which uses the string constructor). - 这种行为非常类似于BigDecimal(double)构造函数(而不是使用字符串构造函数的valueOf(double))。
- The problem can be circumvented with a double rounding step to a higher precision first, but it is complicated and I am not going into the details here
- 这个问题可以用一个双圆的步骤来解决,但它是复杂的,我不打算详细讲。
For those reasons and everything mentioned above in this post I cannot recommend to use DoubleRounder.
由于上述原因和上述内容,我不建议使用DoubleRounder。
#23
2
DecimalFormat is the best ways to output, but I don't prefer it. I always do this all the time, because it return the double value. So I can use it more than just output.
DecimalFormat是输出的最好方法,但我不喜欢它。我总是这样做,因为它返回了双重值。所以我可以用它不仅仅是输出。
Math.round(selfEvaluate*100000d.0)/100000d.0;
OR
或
Math.round(selfEvaluate*100000d.0)*0.00000d1;
If you need large decimal places value, you can use BigDecimal instead. Anyways .0
is important. Without it the rounding of 0.33333d5 return 0.33333 and only 9 digits are allows. The second function without .0
has problems with 0.30000 return 0.30000000000000004.
如果需要大的小数位数,可以使用BigDecimal。不管怎样。0是很重要的。没有它,0。33333d5返回0。33333,只有9个数字是允许的。第二个函数没有。0有0。30000返回0.30000000000000004的问题。
#24
1
Where dp = decimal place you want, and value is a double.
在这里,dp =小数点后,值为2。
double p = Math.pow(10d, dp);
double result = Math.round(value * p)/p;
#25
1
Keep in mind that String.format() and DecimalFormat produce string using default Locale. So they may write formatted number with dot or comma as a separator between integer and decimal parts. To make sure that rounded String is in the format you want use java.text.NumberFormat as so:
请记住,string .format()和DecimalFormat使用默认语言环境生成字符串。因此,他们可以用点或逗号作为整数和小数部分之间的分隔符。要确保圆型字符串是您想要使用java.text的格式。NumberFormat所以:
Locale locale = Locale.ENGLISH;
NumberFormat nf = NumberFormat.getNumberInstance(locale);
// for trailing zeros:
nf.setMinimumFractionDigits(2);
// round to 2 digits:
nf.setMaximumFractionDigits(2);
System.out.println(nf.format(.99));
System.out.println(nf.format(123.567));
System.out.println(nf.format(123.0));
Will print in English locale (no matter what your locale is): 0.99 123.57 123.00
将打印在英语地区(无论您的地区是什么):0.99123.57 123.00 ?
The example is taken from Farenda - how to convert double to String correctly.
这个例子来自Farenda——如何正确地将double转换为字符串。
#26
1
If you Consider 5 or n number of decimal. May be this answer solve your prob.
如果你考虑5或n位数的小数。也许这个答案可以解决你的问题。
double a = 123.00449;
double roundOff1 = Math.round(a*10000)/10000.00;
double roundOff2 = Math.round(roundOff1*1000)/1000.00;
double roundOff = Math.round(roundOff2*100)/100.00;
System.out.println("result:"+roundOff);
Output will be: 123.01
this can be solve with loop and recursive function.
输出将是:123.01这可以用循环和递归函数来解决。
#27
1
DecimalFormat myFormatter = new DecimalFormat("0.000");
String output = myFormatter.format(2.34d);
#28
1
If you're using a technology that has a minimal JDK. Here's a way without any Java libs:
如果您使用的是一个具有最小JDK的技术。这里有一个没有任何Java libs的方法:
double scale = 100000;
double myVal = 0.912385;
double rounded = (int)((myVal * scale) + 0.5d) / scale;
#29
1
To achieve this we can use this formatter:
为了达到这个目的,我们可以使用这个格式化程序:
DecimalFormat df = new DecimalFormat("#.00");
String resultado = df.format(valor)
or:
或者:
DecimalFormat df = new DecimalFormat("0.00"); :
Use this method to get always two decimals:
用这个方法得到两个小数:
private static String getTwoDecimals(double value){
DecimalFormat df = new DecimalFormat("0.00");
return df.format(value);
}
Defining this values:
定义这个值:
91.32
5.22
11.5
1.2
2.6
Using the method we can get this results:
使用这个方法我们可以得到这个结果:
91.32
5.22
11.50
1.20
2.60
在线演示。
#30
0
In general, rounding is done by scaling: round(num / p) * p
一般来说,四舍五入是通过缩放来完成的:圆形(num / p) * p。
/**
* MidpointRounding away from zero ('arithmetic' rounding)
* Uses a half-epsilon for correction. (This offsets IEEE-754
* half-to-even rounding that was applied at the edge cases).
*/
double RoundCorrect(double num, int precision) {
double c = 0.5 * EPSILON * num;
// double p = Math.pow(10, precision); //slow
double p = 1; while (precision--> 0) p *= 10;
if (num < 0)
p *= -1;
return Math.round((num + c) * p) / p;
}
// testing edge cases
RoundCorrect(1.005, 2); // 1.01 correct
RoundCorrect(2.175, 2); // 2.18 correct
RoundCorrect(5.015, 2); // 5.02 correct
RoundCorrect(-1.005, 2); // -1.01 correct
RoundCorrect(-2.175, 2); // -2.18 correct
RoundCorrect(-5.015, 2); // -5.02 correct