在Java中如何将数字四舍五入到小数点后n位
我想要的是一种将double转换为字符串的方法,该方法使用向上舍入法进行四舍五入-即,如果要舍入的小数点为5,它总是向上舍入到下一个数字。这是大多数人在大多数情况下期望的标准四舍五入方法 我还希望只显示有效数字,即不应有任何尾随零 我知道这样做的一种方法是使用在Java中如何将数字四舍五入到小数点后n位,java,decimal,rounding,digits,Java,Decimal,Rounding,Digits,我想要的是一种将double转换为字符串的方法,该方法使用向上舍入法进行四舍五入-即,如果要舍入的小数点为5,它总是向上舍入到下一个数字。这是大多数人在大多数情况下期望的标准四舍五入方法 我还希望只显示有效数字,即不应有任何尾随零 我知道这样做的一种方法是使用String.format方法: String.format("%.5g%n", 0.912385); 返回: 0.91239 0.91230 0.91238 这很好,但是它总是显示带有5位小数的数字,即使它们不重要: String
String.format
方法:
String.format("%.5g%n", 0.912385);
返回:
0.91239
0.91230
0.91238
这很好,但是它总是显示带有5位小数的数字,即使它们不重要:
String.format("%.5g%n", 0.912300);
返回:
0.91239
0.91230
0.91238
另一种方法是使用DecimalFormatter
:
DecimalFormat df = new DecimalFormat("#.#####");
df.format(0.912385);
返回:
0.91239
0.91230
0.91238
但是,正如您所看到的,这使用了半偶数舍入。也就是说,如果前一个数字是偶数,它将向下取整。我想要的是:
0.912385 -> 0.91239
0.912300 -> 0.9123
在Java中实现这一点的最佳方法是什么?假设
值
是双精度,您可以执行以下操作:
(double)Math.round(value * 100000d) / 100000d
这是5位数的精度。零的数量表示小数的数量。假设值
为双精度
,则可以执行以下操作:
(double)Math.round(value * 100000d) / 100000d
double myNum = .912385;
int precision = 10000; //keep 4 digits
myNum= Math.floor(myNum * precision +.5)/precision;
这是5位数的精度。零的数量表示小数的数量。使用,显式设置以处理半偶数轮的问题,然后使用所需输出的格式模式
double myNum = .912385;
int precision = 10000; //keep 4 digits
myNum= Math.floor(myNum * precision +.5)/precision;
例如:
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));
}
给出输出:
12
123.1235
0.23
0.1
2341234.2125
编辑:原始答案不涉及双值的准确性。如果你不太在乎它是向上还是向下,那就好了。但是如果您想要精确的舍入,那么您需要考虑值的预期精度。浮点值在内部具有二进制表示形式。这意味着像2.7735这样的值实际上在内部并没有精确的值。它可以稍大或稍小。如果内部值稍小,则不会四舍五入到2.7740。要纠正这种情况,您需要了解正在使用的值的准确性,并在四舍五入之前加上或减去该值。例如,当您知道您的值精确到6位时,若要将中间值向上舍入,请将该精度添加到值中:
Double d = n.doubleValue() + 1e-6;
要向下取整,请减去精度 使用,显式设置以处理半偶数轮的问题,然后使用所需输出的格式模式
例如:
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));
}
给出输出:
12
123.1235
0.23
0.1
2341234.2125
编辑:原始答案不涉及双值的准确性。如果你不太在乎它是向上还是向下,那就好了。但是如果您想要精确的舍入,那么您需要考虑值的预期精度。浮点值在内部具有二进制表示形式。这意味着像2.7735这样的值实际上在内部并没有精确的值。它可以稍大或稍小。如果内部值稍小,则不会四舍五入到2.7740。要纠正这种情况,您需要了解正在使用的值的准确性,并在四舍五入之前加上或减去该值。例如,当您知道您的值精确到6位时,若要将中间值向上舍入,请将该精度添加到值中:
Double d = n.doubleValue() + 1e-6;
要向下取整,请减去精度 您也可以使用
DecimalFormat df = new DecimalFormat("#.00000");
df.format(0.912385);
DecimalFormat df = new DecimalFormat("#.00000");
df.format(0.912385);
要确保后面有0。您还可以使用
DecimalFormat df = new DecimalFormat("#.00000");
df.format(0.912385);
new BigDecimal(String.valueOf(double)).setScale(yourScale, BigDecimal.ROUND_HALF_UP);
DecimalFormat df = new DecimalFormat("#.00000");
df.format(0.912385);
以确保具有尾随的0
new BigDecimal(String.valueOf(double)).setScale(yourScale, BigDecimal.ROUND_HALF_UP);
将为您获取一个BigDecimal
。要从中提取字符串,只需调用BigDecimal
的toString
方法,或者为Java 5+调用toPlainString
方法即可获得纯格式字符串
示例程序:
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));
}
将为您获取一个BigDecimal
。要从中提取字符串,只需调用BigDecimal
的toString
方法,或者为Java 5+调用toPlainString
方法即可获得纯格式字符串
示例程序:
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));
}
Real的Java如何使用此解决方案,它也与Java1.6之前的版本兼容
BigDecimal bd = new BigDecimal(Double.toString(d));
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
return bd.doubleValue();
更新:BigDecimal.ROUND\u HALF\u不推荐使用-使用RoundingMode
Real的Java如何使用此解决方案,它也与Java1.6之前的版本兼容
BigDecimal bd = new BigDecimal(Double.toString(d));
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
return bd.doubleValue();
更新:BigDecimal.ROUND\u HALF\u不推荐使用-使用RoundingMode
假设你有
double d = 9232.129394d;
你可以用
或者没有大十进制
d = Math.round(d*100)/100.0d;
对于这两种解决方案d==9232.13
假设
double d = 9232.129394d;
你可以用
或者没有大十进制
d = Math.round(d*100)/100.0d;
对于这两种解决方案,您可以使用以下实用方法-
public static double round(double valueToRound, int numberOfDecimalPlaces)
{
double multipicationFactor = Math.pow(10, numberOfDecimalPlaces);
double interestedInZeroDPs = valueToRound * multipicationFactor;
return Math.round(interestedInZeroDPs) / multipicationFactor;
}
您可以使用以下实用程序方法-
public static double round(double valueToRound, int numberOfDecimalPlaces)
{
double multipicationFactor = Math.pow(10, numberOfDecimalPlaces);
double interestedInZeroDPs = valueToRound * multipicationFactor;
return Math.round(interestedInZeroDPs) / multipicationFactor;
}
@米尔豪斯:舍入的十进制格式非常好:
您也可以使用
DecimalFormat df = new DecimalFormat("#.00000");
df.format(0.912385);
DecimalFormat df = new DecimalFormat("#.00000");
df.format(0.912385);
以确保具有尾随的0
new BigDecimal(String.valueOf(double)).setScale(yourScale, BigDecimal.ROUND_HALF_UP);
我想补充一点,这种方法非常适合提供实际的
数字,舍入机制-不仅在视觉上,而且在处理时
假设:您必须在GUI中实现舍入机制
节目。简单更改结果输出的准确性/精度
更改插入符号格式(即括号内)。以便:
DecimalFormat df = new DecimalFormat("#0.######");
df.format(0.912385);
将作为输出返回:0.912385
DecimalFormat df = new DecimalFormat("#0.#####");
df.format(0.912385);
将作为输出返回:0.91239
DecimalFormat df = new DecimalFormat("#0.####");
df.format(0.912385);
将作为输出返回:0.9124
[编辑:如果插入符号格式类似(“#0.##############”)那么您也可以编辑
输入一个十进制数,例如3.1415926,为了参数起见,输入DecimalFormat
不会产生任何垃圾(例如尾随的零),并将返回:
3.1415926
。如果你是那样想的。当然,这有点冗长
对于一些开发人员来说——但是,嘿,它的内存占用很低
在处理过程中,非常容易实现。]
因此,从本质上讲,DecimalFormat的美妙之处在于它同时处理字符串
外观-以及设置的舍入精度级别。因此:你
得到两个
Math.round(selfEvaluate*100000d.0)/100000d.0;
Math.round(selfEvaluate*100000d.0)*0.00000d1;
Math.round(3.7) // 4
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
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
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
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 ***
public static double round(double value, int precision) {
int scale = (int) Math.pow(10, precision);
return (double) Math.round(value * scale) / scale;
}
double scale = 100000;
double myVal = 0.912385;
double rounded = (int)((myVal * scale) + 0.5d) / scale;
/**
* Round half away from zero ('commercial' rounding)
* Uses correction to offset floating-point inaccuracies.
* Works symmetrically for positive and negative numbers.
*/
public static double round(double num, int digits) {
// epsilon correction
double n = Double.longBitsToDouble(Double.doubleToLongBits(num) + 1);
double p = Math.pow(10, digits);
return Math.round(n * p) / p;
}
// test rounding of half
System.out.println(round(0.5, 0)); // 1
System.out.println(round(-0.5, 0)); // -1
// testing edge cases
System.out.println(round(1.005, 2)); // 1.01
System.out.println(round(2.175, 2)); // 2.18
System.out.println(round(5.015, 2)); // 5.02
System.out.println(round(-1.005, 2)); // -1.01
System.out.println(round(-2.175, 2)); // -2.18
System.out.println(round(-5.015, 2)); // -5.02
DecimalFormat df = new DecimalFormat("#.00");
String resultado = df.format(valor)
DecimalFormat df = new DecimalFormat("0.00"); :
private static String getTwoDecimals(double value){
DecimalFormat df = new DecimalFormat("0.00");
return df.format(value);
}
91.32
5.22
11.5
1.2
2.6
91.32
5.22
11.50
1.20
2.60
double num = 4.898979485566356;
DecimalFormat df = new DecimalFormat("#.##");
time = Double.valueOf(df.format(num));
System.out.println(num); // 4.89
BigDecimal bd = new BigDecimal("1363.2749");
bd = bd.setScale(2, RoundingMode.HALF_UP);
System.out.println(bd.doubleValue());
private double round(double value, int places) throws IllegalArgumentException {
if (places < 0) throw new IllegalArgumentException();
// Cast the number to a String and then separate the decimals.
String stringValue = Double.toString(value);
String decimals = stringValue.split("\\.")[1];
// Round all the way to the desired number.
BigDecimal bd = new BigDecimal(stringValue);
for (int i = decimals.length()-1; i >= places; i--) {
bd = bd.setScale(i, RoundingMode.HALF_UP);
}
return bd.doubleValue();
}
double amount = 1000.431;
NumberFormat formatter = new DecimalFormat("##.00");
String output = formatter.format(amount);
System.out.println("output = " + output);
output = 1000.43