You can try BigDecimal for this purpose
Double toBeTruncated = new Double("3.5789055");
Double truncatedDouble = BigDecimal.valueOf(toBeTruncated)
.setScale(3, RoundingMode.HALF_UP)
.doubleValue();
Answer from Neel on Stack OverflowYou can try BigDecimal for this purpose
Double toBeTruncated = new Double("3.5789055");
Double truncatedDouble = BigDecimal.valueOf(toBeTruncated)
.setScale(3, RoundingMode.HALF_UP)
.doubleValue();
You can't set the precision of a double (or Double) to a specified number of decimal digits, because floating-point values don't have decimal digits. They have binary digits.
You will have to convert into a decimal radix, either via BigDecimal or DecimalFormat, depending on what you want to do with the value later.
See also my answer to this question for a refutation of the inevitable *100/100 answers.
Videos
I came across a piece of code in a legacy Java 8 application at work which adds two doubles and gives out a double. I observed that the resulting doubles for various inputs had variable number of digits after the decimal point. Some were very precise with 12 digits after the decimal point and some had merely a digit after the decimal point.
I’m curious to know what factors affect certain doubles to be so very precise and certain doubles not as much.
Examples:
double one = 3880.95; double two = 380.9; Result: 4261.849999999999
double one = 1293.65; double two = 1293.6; Result: 2587.25
Use setRoundingMode, set the RoundingMode explicitly to handle your issue with the half-even round, then use the format pattern for your required output.
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
EDIT: The original answer does not address the accuracy of the double values. That is fine if you don't care much whether it rounds up or down. But if you want accurate rounding, then you need to take the expected accuracy of the values into account. Floating point values have a binary representation internally. That means that a value like 2.7735 does not actually have that exact value internally. It can be slightly larger or slightly smaller. If the internal value is slightly smaller, then it will not round up to 2.7740. To remedy that situation, you need to be aware of the accuracy of the values that you are working with, and add or subtract that value before rounding. For example, when you know that your values are accurate up to 6 digits, then to round half-way values up, add that accuracy to the value:
Double d = n.doubleValue() + 1e-6;
To round down, subtract the accuracy.
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.
To have decimal precision, use BigDecimal class.
Number of decimal places can be specified in setScale as below
BigDecimal a = new BigDecimal("0.25");
a = a.setScale(3, BigDecimal.ROUND_HALF_EVEN);
One possible solution is to use toString() cut off at the decimal point using split("."). If the length of the resulting string is less than 3, add zeroes until the length is three. If it is greater than three, cut off there. Such as:
public String triplePrecision(Float float) {
String tmp = float.toString();
int length = tmp.split(".")[1].length();//numbers after decimal
for (int i = 0; i < 3 - length; i++) {
tmp += "0"; //appending zeroes
}
return tmp.substring(0, indexOf(".") + 3); //start to 3 places after decimal
}
Yes, use java.math.BigDecimal class. It can represent numbers with great precision.
If you just need huge integers, you can use java.math.BigInteger instead.
They both extend java.math.Number.
You can even use your existing doubles if you need:
double d = 67.67;
BigDecimal bd = new BigDecimal(d);
And you can get BigDecimal values out of databases with JDBC:
ResultSet rs = st.executeQuery();
while(rs.next()) {
BigDecimal bd = rs.getBigDecimal("column_with_number");
}
Unfortunately, since Java does not support operator overloading, you can't use regular symbols for common mathematical operations like you would in C# and the decimal type.
You will need to write code like this:
BigDecimal d1 = new BigDecimal(67.67);
BigDecimal d2 = new BigDecimal(67.68);
BidDecimal d3 = d1.add(d2); // d1 + d2 is invalid
Yes: the java.math.BigDecimal class.