How to round a number in Java - java

I need the following results:
10.17111 -> 10.17
10.17445 -> 10.18
I tried BigDecimal and DecimalFormat methods and RoundingMode class:
String value = "10.17111";
BigDecimal bd = new BigDecimal(value);
BigDecimal bdResult = bd.setScale(2, RoundingMode.UP);
String result = bdResult.toString();
System.out.println(result);
Print out = 10.18
Should be = 10.17
double ddd = 10.17111;
DecimalFormat d = new DecimalFormat("#.##");
d.setRoundingMode(RoundingMode.UP);
String outputResult = d.format(ddd).replace(',', '.');
System.out.println(outputResult);
Print out = 10.18
Should be = 10.17
And with BigDecimal:
String value2 = "10.17445";
Print out = 10.18
As I expected
And with DecimalFormat:
double ddd2 = 10.17445;
Print out = 10.17
Should be = 10.18

If you really want to round digit-by-digit and you should really think long and hard about it (and perhaps tell us why if you are so inclined as I'm curious), then you can do any of the following, which I present as a thought exercise rather than as a recommendation that this is mathematically sound which I leave to you to decide for yourself:
1) Write an algorithm which checks from the digit you are rounding to and looks to see if it is a chain of 4's followed by a digit greater (10.44449) than 5 or just a number greater than 5 (10.49). If so round up to 11, otherwise use the normal rules.
2) Use RoundingMode.HALF_UP in a loop or recursively doing one digit at a time. If you have 10.17445, then you define a decimal format #.#### and round. Then #.### and round. Then #.## and round.
The reason there isn't a standard way to do this is because it is not standard.

Just do all of the digits one by one, starting from the end, until you've done as many as you need to do.
public static BigDecimal RoundIt(BigDecimal valueToRound, int precision)
{
BigDecimal result = valueToRound;
for (int i = valueToRound.precision(); i >= precision; i--)
{
result = result.setScale(i, RoundingMode.HALF_UP);
}
return result;
}

My workaround and it works fine:
public static String roundUp(String value) {
BigDecimal bd = new BigDecimal(value.replace(',', '.'));
BigDecimal bdResult = bd.setScale(4, RoundingMode.HALF_UP);
BigDecimal bdResult2 = bdResult.setScale(3, RoundingMode.HALF_UP);
BigDecimal bdResult3 = bdResult2.setScale(2, RoundingMode.HALF_UP);
String result = bdResult3.toString();
return result;
}

Related

ceil or round off after decimal value in Java

I have a decimal value 46.58 i want it to be like 46.60 or for 46.44 it will be like 46.40.
Tried several ways like like Math class's round function and Bigdecimal but it is not roudning off after decimal values.
BigDecimal bigDecimal = new BigDecimal(value);
bigDecimal = bigDecimal.setScale(2,BigDecimal.ROUND_HALF_UP);
value = bigDecimal.doubleValue();
double value = Math.round(decimalValue);
You first need to round to 1 decimal place using standard half-up RoundingMode and afterwards increase the scale to 2 again:
BigDecimal bigDecimal = new BigDecimal("46.58");
bigDecimal = bigDecimal.setScale(1, RoundingMode.HALF_UP); // bigDecimal == 46.6
bigDecimal = bigDecimal.setScale(2, RoundingMode.UNNECESSARY); // bigDecimal == 46.60
below solution worked for me.
BigDecimal bigDecimal = new BigDecimal("46.58");
bigDecimal = bigDecimal.setScale(1, RoundingMode.HALF_UP);
bigDecimal = bigDecimal.setScale(2, RoundingMode.UNNECESSARY);
double d = bigDecimal.doubleValue();
String valstr = String.format("%.2f%n", d);
System.out.println(valstr);

BigDecimal with decimates value?

I'm trying divide a value using BigDecimal, when this value is a decimates BigDecimal round this value and I wont to do that. I need the decimates value are shown. For example, if I do divide 10 / 3 = 3.33333, I need shown 3.33 but does show 3.00
How could I do this ?
//Result-> 10 / 2 = 3,3333333
BigDecimal result = new BigDecimal(0);
BigDecimal v1 = new BigDecimal(10);
BigDecimal v2 = new BigDecimal(3);
result = v1.divide(v2, BigDecimal.ROUND_UP);
//output = 3
//I need output = 3.33
The scale of BigDecimals that were initialized with ints is 0, meaning that rounding operations round to unity. With your example, the division rounds up to 4.
Set the scale of the first BigDecimal to 2, which be retained through the division. Also set the rounding mode to "down".
BigDecimal v1 = new BigDecimal(10).setScale(2);
BigDecimal v2 = new BigDecimal(3);
result = v1.divide(v2, BigDecimal.ROUND_DOWN);
Printing results now yields an output of 3.33.
You could have also used the RoundingMode enum as a drop-in replacement for the rounding constants. Additionally, you could have used ROUND_HALF_DOWN, ROUND_HALF_UP, or ROUND_HALF_EVEN (or their RoundingMode equivalents).
You could use a string with the appropriate number of decimal digits to set the scale implicitly.
BigDecimal v1 = new BigDecimal("10.00"); // scale of 2
try to compile and run this java class, it works as you wish:
import java.math.*;
class decimal {
public static void main(String[] args) {
BigDecimal result = new BigDecimal(0);
BigDecimal v1 = new BigDecimal(10);
BigDecimal v2 = new BigDecimal(3);
result = v1.divide(v2,2,BigDecimal.ROUND_HALF_UP);
System.out.println(result);
}
}
output : 3.33
you want two decimal digits this is why I set scale=2
Try to add scale to BigDecimal, like this:
public class User {
public static void main(String[] args) {
BigDecimal result = new BigDecimal(0);
BigDecimal v1 = new BigDecimal(10).setScale(2);
BigDecimal v2 = new BigDecimal(3);
result = v1.divide(v2, BigDecimal.ROUND_DOWN);
System.out.println(result);
}
}

How to always round off upto 2 decimal places in java

I have tried the following code but it is not working in a particular case.
Eg: Suppose, I have a double value=2.5045 and i want it to be rounded off upto two decimal places using the below code.After rounding off, i get the answer as 2.5. But I want the answer to be 2.50 instead. In this case,zero is trimmed off. Is there any way to retain the zero so as to get the desired answer as 2.50 after rounding off.
private static DecimalFormat twoDForm = new DecimalFormat("#.##");
public static double roundTwoDecimals(double amount) {
return Double.valueOf(twoDForm.format(amount));
}
try this pattern
new DecimalFormat("0.00");
but this will change only formatting, double cannot hold number of digits after decimal poin, try BigDecimal
BigDecimal bd = new BigDecimal(2.5045).setScale(2, RoundingMode.HALF_UP);
Look at the documentation for DecimalFormat. For # it says:
Digit, zero shows as absent
0 is probably what you want:
Digit
So what you are looking for is either "0.00" or "#.00" as a format string, depending on whether you want the first digit before the period, to be visible in case the numbers absolute value is smalle than 0.
Try this
DecimalFormat format = new DecimalFormat("#");
format.setMinimumFractionDigits(2);
answer.setText(format.format(data2));
Try This
double d = 4.85999999999;
long l = (int)Math.round(d * 100); // truncates
d = l / 100.0;
You are returning a double. But double or Double are objects representing a number and don't carry any formatting information. Ìf you need to output two decimal places the point to do this is when you convert your double to a String.
use # if you want to ignore 0
new DecimalFormat("###,#0.00").format(d)
There is another way to achieve this . I have already posted answer in post
will just answer again here. As we will require rounding off values many times .
public class RoundingNumbers {
public static void main(String args[]){
double number = 2.5045;
int decimalsToConsider = 2;
BigDecimal bigDecimal = new BigDecimal(number);
BigDecimal roundedWithScale = bigDecimal.setScale(decimalsToConsider, BigDecimal.ROUND_HALF_UP);
System.out.println("Rounded value with setting scale = "+roundedWithScale);
bigDecimal = new BigDecimal(number);
BigDecimal roundedValueWithDivideLogic = bigDecimal.divide(BigDecimal.ONE,decimalsToConsider,BigDecimal.ROUND_HALF_UP);
System.out.println("Rounded value with Dividing by one = "+roundedValueWithDivideLogic);
}
}
Output we will get is
Rounded value with setting scale = 2.50
Rounded value with Dividing by one = 2.50
double kilobytes = 1205.6358;
double newKB = Math.round(kilobytes*100.0)/100.0;
DecimalFormat df = new DecimalFormat("###.##");
System.out.println("kilobytes (DecimalFormat) : " + df.format(kilobytes));
Try this if u are still getting the above problem

Java BigDecimal without E

I have a BigDecimal variable
BigDecimal x = new BigDecimal("5521.0000000001");
Formula:
x = x.add(new BigDecimal("-1")
.multiply(x.divideToIntegralValue(new BigDecimal("1.0"))));
I want to remove the integer part, to get the value x = ("0.0000000001"), but my new value is 1E-10 and not the 0.0000000001.
To get a String representation of the BigDecimal without the exponent part, you can use
BigDecimal.toPlainString(). In your example:
BigDecimal x = new BigDecimal("5521.0000000001");
x = x.add(new BigDecimal("-1").
multiply(x.divideToIntegralValue(new BigDecimal("1.0"))));
System.out.println(x.toPlainString());
prints
0.0000000001
Try using BigDecimal.toPlainString() to get value as plain string as you require.
Perhaps using BigDecimal isn't really helping you.
double d = 5521.0000000001;
double f = d - (long) d;
System.out.printf("%.10f%n", f);
prints
0.0000000001
but the value 5521.0000000001 is only an approximate representation.
The actual representation is
double d = 5521.0000000001;
System.out.println(new BigDecimal(d));
BigDecimal db = new BigDecimal(d).subtract(new BigDecimal((long) d));
System.out.println(db);
prints
5521.000000000100044417195022106170654296875
1.00044417195022106170654296875E-10
I suspect whatever you are trying to is not meaningful as you appear to be trying to obtain a value which is not what you think it is.
If you want to do this at your BigDecimal object and not convert it into a String with a formatter you can do it on Java 8 with 2 steps:
stripTrailingZeros()
if scale < 0 setScale to 0 if don't like esponential/scientific
notation
You can try this snippet to better understand the behaviour
BigDecimal bigDecimal = BigDecimal.valueOf(Double.parseDouble("50"));
bigDecimal = bigDecimal.setScale(2);
bigDecimal = bigDecimal.stripTrailingZeros();
if (bigDecimal.scale()<0)
bigDecimal= bigDecimal.setScale(0);
System.out.println(bigDecimal);//50
bigDecimal = BigDecimal.valueOf(Double.parseDouble("50.20"));
bigDecimal = bigDecimal.setScale(2);
bigDecimal = bigDecimal.stripTrailingZeros();
if (bigDecimal.scale()<0)
bigDecimal= bigDecimal.setScale(0);
System.out.println(bigDecimal);//50.2
bigDecimal = BigDecimal.valueOf(Double.parseDouble("50"));
bigDecimal = bigDecimal.setScale(2);
bigDecimal = bigDecimal.stripTrailingZeros();
System.out.println(bigDecimal);//5E+1
bigDecimal = BigDecimal.valueOf(Double.parseDouble("50.20"));
bigDecimal = bigDecimal.setScale(2);
bigDecimal = bigDecimal.stripTrailingZeros();
System.out.println(bigDecimal);//50.2

Extract number decimal in BigDecimal

How to extract a number after the decimal point using BigDecimal ?
BigDecimal d = BigDecimal.valueOf(1548.5649);
result : extract only : 5649
Try:
BigDecimal d = BigDecimal.valueOf(1548.5649);
BigDecimal result = d.subtract(d.setScale(0, RoundingMode.FLOOR)).movePointRight(d.scale());
System.out.println(result);
prints:
5649
Try BigDecimal.remainder:
BigDecimal d = BigDecimal.valueOf(1548.5649);
BigDecimal fraction = d.remainder(BigDecimal.ONE);
System.out.println(fraction);
// Outputs 0.5649
This should do the trick:
d.subtract(d.setScale(0, RoundingMode.FLOOR));
setScale() rounds the number to zero decimal places, and despite its name, does not mutate the value of d.
If the value is negative, using d.subtract(d.setScale(0, RoundingMode.FLOOR)) will return a wrong decimal.
Use this:
BigInteger decimal =
d.remainder(BigDecimal.ONE).movePointRight(d.scale()).abs().toBigInteger();
It returns 5649 for 1548.5649 or -1548.5649
You don't tell which type you want as a result. The easiest way is probably to transform the BigDecimal into a String, and take a substring:
String s = d.toPlainString();
int i = s.indexOf('.');
if (i < 0) {
return "";
}
return s.substring(i + 1);
try to use d.doubleValue() to get the double value

Categories

Resources