multiplying DecimalFormat number (no longer rounded properly) - java

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));

Related

How to round numbers, remove "E"s from them and remove decimal points from whole numbers?

I have a crypto portfolio made, but the long percentage numbers or the "E"s instead of big numbers really tear up the design, like in this example:
How to fix them (round up to 2 decimal digits, remove E, remove .0 from 5)?
Try this:
Math.round(number * 100.0) / 100.0;
You can find plenty of other ways if you search.
Using the Double constructor, you can turn all of those strings into doubles.
String someNumberString = "1.2E5";
Double dNum = new Double(someNumberString);
You can do rounding as such:
double rounded = (Math.round(dNum * ROUND_TO_OFFSET) / ROUND_TO_OFFSET)
where ROUND_TO_OFFSET specifies the digit to round to. E.g. ROUND_TO_OFFSET= 100 rounds to the nearest 0.01. This has a disadvantage though. Math.round returns a long, so if your dNum * ROUND_TO_OFFSET produces a number that is larger or smaller than a long can hold, it will not work correctly.
You can format any double into a nice, easy to read format with the DecimalFormat class.
DecimalFormat decimalFormat = new DecimalFormat("#,##0.#####");
String formattedDouble = decimalFormat.format(someDouble);
This allows you to easily convert double values to strings that look like this:
1,234,567.89012
If you need more precision or numbers larger than what Long.MAX_VALUE can handle, you should checkout java's BigDecimal class.
BigDecimal provides it's own round method that allows you to specify what to round to. You can still use the DecimalFormat class by calling BigDecimal's doubleValue() function.

Strange BigDecimal value using DecimalFormat

I'm trying to convert some string values in number using DecimalFormat. I try to explain you my problem in a better way:
I have the following method:
private BigDecimal loadBigDecimal(String value){
BigDecimal bigDecimalToReturn = null;
DecimalFormat df = new DecimalFormat("##.###");
bigDecimalToReturn = new BigDecimal(df.parse(value).doubleValue());
return bigDecimalToReturn;
}
Now if I try to run the method:
BigDeciaml dec = myObject.loadBigDecimal("120,11");
The value of dec is 120.1099999999999994315658113919198513031005859375.
Why decimalFormat is changing the scale of my value?
You are doing conversion to double and backwards. That's unnecessary and introduces rounding errors. You should use the following code:
private BigDecimal loadBigDecimal(String value) throws ParseException {
DecimalFormat df = new DecimalFormat("##.###");
df.setParseBigDecimal(true);
return (BigDecimal) df.parse(value);
}
Doubles are only approximations. That is correct for a double. If you want a specific scale, you need to tell it in the BigDecimal constructor.
That is because of the df.parse(value).doubleValue() call. At this point, the value is converted to a double.
double represent plus or minus the sum of powers of 2 (with positive and negative exponents).
One can write 120 as 64+32+16+8.
But one can't write 0.11 as a finite sum of power of 2.
So there is an approximation.
0.1099999999999994315658113919198513031005859375
Which is a sum of power of 2.
It's look like BigDecimal as a constructor with a string for parameter. Maybe you can just use it.
BigDecimal dec = new BigDecimal("120,11");

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

Java, rounding a double to two decimal places

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));
}

Categories