This question already has an answer here:
Rounding BigDecimal to *always* have two decimal places
(1 answer)
Closed 2 years ago.
Below code gives me about 14 decimal places. How can i trim it to the 2 decimal place?
public class BigDecimalGenerator
{ public static void main(String[] args)
{ BigDecimal max = new BigDecimal("50.00");
BigDecimal min = new BigDecimal("-50.00");
BigDecimal range = max.subtract(min);
BigDecimal result = min.add(range.multiply(new BigDecimal(Math.random())));
System.out.println(result); }
}
Use this method on BigDecimal
setScale(int newScale, int roundingMode)
using the desired scale (2) and roundingmode.
Set the rounding mode and scale.
BigDecimal max = new BigDecimal("50.00");
BigDecimal min = new BigDecimal("-50.00");
BigDecimal range = max.subtract(min);
BigDecimal result = min
.add(range.multiply(new BigDecimal(Math.random())));
result = result.setScale(2,RoundingMode.HALF_UP);
System.out.println(result);
Prints something like.
-31.28
Related
This question already has answers here:
how does java.math.RoundingMode work?
(4 answers)
How to round a number to n decimal places in Java
(39 answers)
Closed 2 years ago.
I have been sitting on this for a day now thinking like a 5th grade school student.
public class Tester
{
static String actualValue = "";
private static DecimalFormat df2 = new DecimalFormat("#.##"); //To round off to two decimal places.
static double regPrice = 0.0;
static double regPrice2 = 0.0;
public static void main(String[] args)
{
regPrice2 = 1506.365;
System.out.println("reg price 1 is: "+regPrice2);
System.out.println("reg price 1 after rounding is is: "+round(regPrice2));
regPrice = 8535.765;
System.out.println("reg price is: "+regPrice);
System.out.println("reg price after rounding is: "+round(regPrice));
}
public static double round(double value)
{
df2.setRoundingMode(RoundingMode.HALF_UP);
String returnValue = df2.format(value);
double actualValue = Double.parseDouble(returnValue);
return actualValue;
}
}
Output
Value 1
Value 2
Actual
1506.37
8535.76
Expected
1506.37
8535.77
Why is the rounding off working for the first number but not the second?
How can I make this work?
Thank to the floating-pointrepresentation, what you think 1506.365 or 8535.765 is actually number slightly greater or less than you expect. The floating-point numbers are represented as mantissa and exponent. Hence for example for 0.365 and 0.765 rounding is done differently. Rounding near halves then appears as in random direction. Use BigDecimal if you need a precise number.
This question already has answers here:
Rounding Bigdecimal values with 2 Decimal Places
(5 answers)
Closed 2 years ago.
I have been looking for answers here re: rounding and BigDecimal, but I am having trouble. Can someone help?
The actual result of the below division is 11.469...
BigDecimal a = new BigDecimal(0.32);
BigDecimal b = new BigDecimal(2.79);
BigDecimal diffPercent = (a.divide(b, 2, RoundingMode.HALF_EVEN)).multiply(HUNDRED); // 11.00
BigDecimal diffPercent = (a.divide(b, 4, RoundingMode.HALF_EVEN)).multiply(HUNDRED); // 11.4700
How can I get 11.47 (two decimal places)?
Instead of multiplying by BigDecimal(100), move the decimal point to the right:
BigDecimal diffPercent = (a.divide(b, 4, RoundingMode.HALF_EVEN)).movePointRight(2)
Output: 11.47
This works because moving the decimal point only adjusts the scale of the BigDecimal.
BigDecimal bg = new BigDecimal("11.468");
MathContext mc = new MathContext(3); // 3 precision
// bg1 is rounded using mc
final BigDecimal round = bg.round(mc, RoundingMode.CEILING);
System.out.println(round);
Posting as this is another example of how to round
I have a group of doubles with a varying number of decimal places. I have a need to get the SUM() of those values and then normalize them all so that they SUM() to 1. Furthermore I have a requirement that in the final results we limit the number of decimal places to 4. To accomplish this I have tried doing the following :
normalizationFactor = 1/sumOfAllDoublesInGroup;
for(Object myObject : myGroupOfObjects){
myObject.setDoubleValue = round(myObject.getDoubleValue * normalizationFactor),4);
}
private Double round (Double doubleValue, Integer decimalPlaces) {
if (places < 0) throw new IllegalArgumentException();
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}
The drawback here is that after rounding I still cannot guarantee that the SUM() of all the doubles is still == 1. I would appreciate some help with that.
To be clear the only requirements are that
1) I get a set of numbers each having a varying number of decimal places.
2) When all is said and done each number is limited to 4 decimal places.
3) The final SUM() of all numbers in the group must EXACTLY = 1
There are many conversions in your code between double and BigDecimal. These conversions may be adding double precision error to your values. Please find the below code, all numbers are stored in BigDecimal.
List<BigDecimal> myGroupOfObjects = new ArrayList<>();
myGroupOfObjects.add(new BigDecimal("0.3"));
myGroupOfObjects.add(new BigDecimal("0.1"));
myGroupOfObjects.add(new BigDecimal("0.2"));
myGroupOfObjects.add(new BigDecimal("0.2"));
BigDecimal sumOfAllDoublesInGroup = new BigDecimal("0.8"); // #HardCoding
BigDecimal normalizationFactor = new BigDecimal("1.0")
.divide(sumOfAllDoublesInGroup);
BigDecimal result = new BigDecimal(0);
for(BigDecimal myObject : myGroupOfObjects){
myObject = myObject.multiply(normalizationFactor)
.setScale(4, RoundingMode.HALF_UP);
result = result.add(myObject);
}
Result:
0.3750
0.1250
0.2500
0.2500
------
1.0
This question already has answers here:
How to nicely format floating numbers to string without unnecessary decimal 0's
(29 answers)
Closed 9 years ago.
How can I make a float value to only show the dot and the decimals if they exist. For example show 17 instead of 17.0 but if I have a 17.2 show the dot and the decimals.
Thanks!
You might also require to limit the length of fraction part, because there might a result like 12.00001 after a sequence of floating point operations. Code snippet I use to nicely format a double to a string:
private static final DecimalFormat[] formats= new DecimalFormat[]{
null,
new DecimalFormat("#.#"),
new DecimalFormat("#.##"),
new DecimalFormat("#.###"),
new DecimalFormat("#.####")
};
public static String toConciseString(double d, int fractionLength){
long asLong = (long) d;
if(Math.abs(d - asLong) < 0.00001d){
return Long.toString(asLong);
}
return formats[fractionLength].format(d);
}
Test cases showing the output examples:
assertThat(toConciseString(23.323, 2)).isEqualTo("23.32");
assertThat(toConciseString(23.329, 2)).isEqualTo("23.33");
assertThat(toConciseString(23.329, 3)).isEqualTo("23.329");
assertThat(toConciseString(23.3, 2)).isEqualTo("23.3");
assertThat(toConciseString(23.30001, 2)).isEqualTo("23.3");
assertThat(toConciseString(23.00001, 2)).isEqualTo("23");
Try this:
DecimalFormat decimalFormat = new DecimalFormat("#0.##");
float float1 = 1.00f;
float float2 = 1.02f;
System.out.println(decimalFormat.format(float1));
System.out.println(decimalFormat.format(float2));
It will print out:
1
1.02
This question already has answers here:
Round a double to 2 decimal places [duplicate]
(13 answers)
Closed 9 years ago.
I have a Double value Double val = 49.569632
How can I roundup the val to get 49.57
You can use the DecimalFormat.
double d = 4.569632;
DecimalFormat df = new DecimalFormat("#.##");
System.out.print(df.format(d));
Or you can use the below method as mentioned in this answer as Luiggi Mendoza suggested.
public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(places, BigDecimal.ROUND_HALF_UP);
return bd.doubleValue();
}
A simple way to round is when printing
double val = 49.569632; // this should be a primitive, not an object
System.out.printf("%.2f%n", val);
or you can round the value first
double rounded = Math.round(val * 1e2) / 1e2;
System.out.println(rounded);
IMHO Using BigDecimal is slower, more complicated to write and no less error prone than using double if you know what you are doing. I know many developer prefer to use a library than write code themselves. ;)