Java, rounding a double to two decimal places - java

I'm trying to round a double to the nearest two decimal places however, it is just rounding to the nearest full number.
For example, 19634.0 instead of 19634.95.
This is the current code I use for the rounding
double area = Math.round(Math.PI*Radius()*Radius()*100)/100;
I can't see where i am going wrong.
Many thanks for any help.

Well, Math.round(Math.PI*Radius()*Radius()*100) is long. 100 is int.
So Math.round(Math.PI*Radius()*Radius()*100) / 100 will become long (19634).
Change it to Math.round(Math.PI*Radius()*Radius()*100) / 100.0. 100.0 is double, and the result will also be double (19634.95).

You can use a DecimalFormat object:
DecimalFormat df = new DecimalFormat ();
df.setMaximumFractionDigits (2);
df.setMinimumFractionDigits (2);
System.out.println (df.format (19634.95));

Do you actually want want to round the value to 2 places, which will cause snowballing rounding errors in your code, or simply display the number with 2 decimal places? Check out String.format(). Complex but very powerful.

You might want to take a look at the DecimalFormat class.
double x = 4.654;
DecimalFormat twoDigitFormat = new DecimalFormat("#.00");
System.out.println("x=" + twoDigitFormat.format());
This gives "x=4.65". The difference between # and 0 in the pattern is that the zeros are always displayed and # will not if the last ones are 0.

The following example came from this forum, but seems to be what you are looking for.
double roundTwoDecimals(double d) {
DecimalFormat twoDForm = new DecimalFormat("#.##");
return Double.valueOf(twoDForm.format(d));
}

Related

multiplying DecimalFormat number (no longer rounded properly)

I'm basically trying to use DecimalFormat to get to two decimal places. I'm taking two integer values then dividing them and casting to a double I've put in sample values below. When I do as below I get a value that is no longer to two decimal places. It seems to be when multiply by the 3 it loses it's rounding.
DecimalFormat df = new DecimalFormat("#.00");
double d = Double.parseDouble(df.format((double)5/6))*3;
System.out.println(d);
Can you let me know why this occurs and how to fix this?
In the statemet:
double d = Double.parseDouble(df.format((double)5/6))*3;
the formatting is not preserved (Double returns a double).
You could do, e.g.:
System.out.println(df.format(d));

Formatting Double to exactly 2 Decimal places IF required

I require a DecimalFormat or a better equivalent of representing a Double value (in Java) which could be:
25 or 25.5
I need for that to be represented as either a whole number (25) or to two decimal places if it has any (25.50). This is because i'm printing it out as money.
I have the following format already:
DecimalFormat decFormat = new DecimalFormat("##,###.##");
This works perfectly if the Double is a whole number; I get the output $25,000. Except if the value is 25,000.5; it prints $25,000.5 when I need it to be printed as $25,000.50. The problem is as stated in the docs:
# a digit, zero shows as absent
So essentially the last zero is dropped off since it is optional.
I cannot do:
DecimalFormat decFormat = new DecimalFormat("##,###.#0");
as that is not allowed.
How can I achieve this?
Note:
These questions are related but do not cover what I need specifically with the DecimalFormat. Most of the answers suggest using a BigDecimal or printf. Is this the best thing to do? I don't have to use DecimalFormat but prefer to since i've started on that path (lots of code everywhere already using it).
Best way to Format a Double value to 2 Decimal places
How do I round a double to two decimal places in Java?
Round a double to 2 decimal places
This is definitely a bit of a hack, but I don't know if the DecimalFormat syntax allows for anything better. This simply checks to see if the number is real, and formats based on the spec you asked for.
double number = 25000.5;
DecimalFormat df;
if(number%1==0)
df = new DecimalFormat("##,###");
else
df = new DecimalFormat("##,###.00");
System.out.println(df.format(number));
When you need to return Decimal Format value this works
import java.text.DecimalFormat;
/**
* #return The weight of this brick in kg.
*/
public double getWeight()
{
DecimalFormat df = new DecimalFormat("#.##");
double number = ( getVolume() * WEIGHT_PER_CM3 ) / 1000;
//System.out.println(df.format(number));
return Double.valueOf ( df.format( number ) );
}

Decimal Formatting is not working

I want to be able to make sure a number only has two decimal places.
E.G Area entered = 256.12345 so Area would be 256.12.
This is what I have:
DecimalFormat df = new DecimalFormat( "#,###,###,##0.00" );
double area = new Double(area.format(area)).doubleValue();
area = (double)(r*r);
You're not actually using the instance df.
Change your code to use it instead of calling methods on area (which won't work, since primitives don't have methods):
double area = new Double(df.format(area)).doubleValue();
However, the formality of precision is more for printing purposes than storing purposes (Double will store it in the IEEE floating point standard for doubles, which may lead to imprecise floating point values).
To get around that, use a BigDecimal instead, with a precision of 2:
BigDecimal decimal = new BigDecimal(area);
decimal.setScale(2);
System.out.println(decimal); // will print area to two decimal places
This is the way you do it.
//formatting numbers upto 2 decimal places in Java
DecimalFormat df = new DecimalFormat("#,###,##0.00");
System.out.println(df.format(364565.14));
System.out.println(df.format(364565.1454));
//formatting numbers upto 3 decimal places in Java
df = new DecimalFormat("#,###,##0.000");
System.out.println(df.format(364565.14));
System.out.println(df.format(364565.1454));
}
}
Output:
364,565.14
364,565.15
364,565.140
364,565.145

Regarding rounding off a value to certain decimal point

I was going through the class decimal format as I was trying format a decimal number in Java upto 2 decimal places or 3 decimal places.
I come up with this solution as shown below but please also let me know are there any other alternative that java provides us to achieve the same thing..!!
import java.text.DecimalFormat;
public class DecimalFormatExample {
public static void main(String args[]) {
//formatting numbers upto 2 decimal places in Java
DecimalFormat df = new DecimalFormat("#,###,##0.00");
System.out.println(df.format(364565.14));
System.out.println(df.format(364565.1454));
//formatting numbers upto 3 decimal places in Java
df = new DecimalFormat("#,###,##0.000");
System.out.println(df.format(364565.14));
System.out.println(df.format(364565.1454));
}
}
Output:
364,565.14
364,565.15
364,565.140
364,565.145
Please advise what are other alternatives that java provide us to achieve the same thing..!!
If you are bothered by re-defining your DecimalFormat, or if you suspect you'll be needing to do redefine many times, you could also do inline formatting with String.format(). Check the syntax for Formatter especially the Numeric sub-title.
Here is an alternative to round off...
double a = 123.564;
double roundOff = Math.round(a * 10.0) / 10.0;
System.out.println(roundOff);
roundOff = Math.round(a * 100.0) / 100.0;
System.out.println(roundOff);
The output is
123.6
123.56
Number of 0s while multiplying and dividing decides the rounding off.
Here is one method.
float round(float value, int roundUpTo){
float x=(float) Math.pow(10,roundUpTo);
value = value*x; // here you will guard your decimal points from loosing
value = Math.round(value) ; //this returns nearest int value
return (float) value/p;
}

Round a double to 2 decimal places [duplicate]

This question already has answers here:
How to round a number to n decimal places in Java
(39 answers)
Closed 8 years ago.
If the value is 200.3456, it should be formatted to 200.34.
If it is 200, then it should be 200.00.
Here's an utility that rounds (instead of truncating) a double to specified number of decimal places.
For example:
round(200.3456, 2); // returns 200.35
Original version; watch out with this
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;
}
This breaks down badly in corner cases with either a very high number of decimal places (e.g. round(1000.0d, 17)) or large integer part (e.g. round(90080070060.1d, 9)). Thanks to Sloin for pointing this out.
I've been using the above to round "not-too-big" doubles to 2 or 3 decimal places happily for years (for example to clean up time in seconds for logging purposes: 27.987654321987 -> 27.99). But I guess it's best to avoid it, since more reliable ways are readily available, with cleaner code too.
So, use this instead
(Adapted from this answer by Louis Wasserman and this one by Sean Owen.)
public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
BigDecimal bd = BigDecimal.valueOf(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}
Note that HALF_UP is the rounding mode "commonly taught at school". Peruse the RoundingMode documentation, if you suspect you need something else such as Bankers’ Rounding.
Of course, if you prefer, you can inline the above into a one-liner:
new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue()
And in every case
Always remember that floating point representations using float and double are inexact.
For example, consider these expressions:
999199.1231231235 == 999199.1231231236 // true
1.03 - 0.41 // 0.6200000000000001
For exactness, you want to use BigDecimal. And while at it, use the constructor that takes a String, never the one taking double. For instance, try executing this:
System.out.println(new BigDecimal(1.03).subtract(new BigDecimal(0.41)));
System.out.println(new BigDecimal("1.03").subtract(new BigDecimal("0.41")));
Some excellent further reading on the topic:
Item 48: "Avoid float and double if exact answers are required" in Effective Java (2nd ed) by Joshua Bloch
What Every Programmer Should Know About Floating-Point Arithmetic
If you wanted String formatting instead of (or in addition to) strictly rounding numbers, see the other answers.
Specifically, note that round(200, 0) returns 200.0. If you want to output "200.00", you should first round and then format the result for output (which is perfectly explained in Jesper's answer).
If you just want to print a double with two digits after the decimal point, use something like this:
double value = 200.3456;
System.out.printf("Value: %.2f", value);
If you want to have the result in a String instead of being printed to the console, use String.format() with the same arguments:
String result = String.format("%.2f", value);
Or use class DecimalFormat:
DecimalFormat df = new DecimalFormat("####0.00");
System.out.println("Value: " + df.format(value));
I think this is easier:
double time = 200.3456;
DecimalFormat df = new DecimalFormat("#.##");
time = Double.valueOf(df.format(time));
System.out.println(time); // 200.35
Note that this will actually do the rounding for you, not just formatting.
The easiest way, would be to do a trick like this;
double val = ....;
val = val*100;
val = Math.round(val);
val = val /100;
if val starts at 200.3456 then it goes to 20034.56 then it gets rounded to 20035 then we divide it to get 200.34.
if you wanted to always round down we could always truncate by casting to an int:
double val = ....;
val = val*100;
val = (double)((int) val);
val = val /100;
This technique will work for most cases because for very large doubles (positive or negative) it may overflow. but if you know that your values will be in an appropriate range then this should work for you.
Please use Apache commons math:
Precision.round(10.4567, 2)
function Double round2(Double val) {
return new BigDecimal(val.toString()).setScale(2,RoundingMode.HALF_UP).doubleValue();
}
Note the toString()!!!!
This is because BigDecimal converts the exact binary form of the double!!!
These are the various suggested methods and their fail cases.
// 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;
double value= 200.3456;
DecimalFormat df = new DecimalFormat("0.00");
System.out.println(df.format(value));
If you really want the same double, but rounded in the way you want you can use BigDecimal, for example
new BigDecimal(myValue).setScale(2, RoundingMode.HALF_UP).doubleValue();
double d = 28786.079999999998;
String str = String.format("%1.2f", d);
d = Double.valueOf(str);
For two rounding digits. Very simple and you are basically updating the variable instead of just display purposes which DecimalFormat does.
x = Math.floor(x * 100) / 100;
Rounding a double is usually not what one wants. Instead, use String.format() to represent it in the desired format.
In your question, it seems that you want to avoid rounding the numbers as well? I think .format() will round the numbers using half-up, afaik?
so if you want to round, 200.3456 should be 200.35 for a precision of 2. but in your case, if you just want the first 2 and then discard the rest?
You could multiply it by 100 and then cast to an int (or taking the floor of the number), before dividing by 100 again.
200.3456 * 100 = 20034.56;
(int) 20034.56 = 20034;
20034/100.0 = 200.34;
You might have issues with really really big numbers close to the boundary though. In which case converting to a string and substring'ing it would work just as easily.
value = (int)(value * 100 + 0.5) / 100.0;

Categories