ceil or round off after decimal value in Java - 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);

Related

How to round a number in 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;
}

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

BigDecimal doesn't calculate divide

I divided 124/13. but the app forced close.
this is my code:
Float x =Float.valueOf(a.getText().toString());
Float y =Float.valueOf(b.getText().toString());
BigDecimal xx= new BigDecimal (x);
BigDecimal yy= new BigDecimal (y);
BigDecimal rx= xx.divide(yy);
res.setText("=" + rx);
It is possible that the app is crashing, because BigDecimal.toString() does something unexpected. Also a, or b or rx may be null.
In any way, I would consider using BigDecimal with the String constructor, such that no rounding errors occur:
String x = a.getText().toString();
String y = b.getText().toString();
BigDecimal xx = new BigDecimal(x);
BigDecimal yy = new BigDecimal(y);
BigDecimal rx = xx.divide(yy);
res.setText("=" + rx.toPlainString());
Also write new BigDecimal(x) instead of new BigDecimal (x). Note the omitted space, that may be the very reason why your app crashes, it is not allowed in Java.
You have encountered:
java.lang.ArithmeticException: Non-terminating decimal expansion;
no exact representable decimal result.
Consider this example, which will yeld this exact exception:
BigDecimal x = new BigDecimal(1);
BigDecimal y = new BigDecimal(3);
BigDecimal result = x.divide(y);
That's because there's no exact representation of 0.3333(3).
What you need to do is to specify rounding and precision:
BigDecimal result = x.divide(y, 10 /*scale*/, RoundingMode.HALF_UP);
System.out.println(result); //will print "0.3333333333"
Also note that you should create the BigDecimal directly from String, as float is not a precise representation. Consider this:
String s = "0.123456789";
System.out.println(Float.parseFloat(s)); //prints 0.12345679
System.out.println(new BigDecimal(s)); //prints 0.123456789
It may be the case that you want an approximate result. Then just go with float or double only:
dobule x = Double.parseDouble(a.getText());
dobule y = Double.parseDouble(b.getText());
res.setText("=" + (x/y));

Difference of Two numbers - BigDecimal

I am just trying to learn more about BigDecimal, but below code makes me confuse.
Double x = 1.2;
String y = "1.2";
BigDecimal a = BigDecimal.ZERO;
BigDecimal b = BigDecimal.ZERO;
a = new BigDecimal(x);
b = new BigDecimal(y);
int res = res = b.compareTo(a);
if(res==1){
System.out.println("Die");
}else if(res ==0){
System.out.println("Live");
}else if (res==-1){
System.out.println("God Loves you");
}
Result = Die
I am not ready to "Die", why BigDecimal is hell bent on killing me.
This statement:
Double x = 1.2;
assigns the nearest double-representable value to 1.2 to x. That's just less than 1.2 - the value 1.2 itself can't be represented exactly in binary.
Now when you create a BigDecimal from that value, that "not quite 1.2" value is retained exactly. From the constructor's documentation:
Translates a double into a BigDecimal which is the exact decimal representation of the double's binary floating-point value.
... whereas when you use new BigDecimal("1.2") the result is exactly 1.2 - BigDecimal parses the string, and any decimal string representation can be represented exactly by BigDecimal, as that's the whole point of it.
1.2 is slightly bigger than "the nearest double representation of 1.2" hence res is 1.
a = new BigDecimal(x); // a= 1.1999999999999999555910790149937383830547332763671875
b = new BigDecimal(y); // b=1.2
This is due to conversion issue since translates a double into a BigDecimal which is the exact decimal representation.
int res = res = b.compareTo(a); //res= 1
Because 1.2 as double is not what you expect it to be.
Try this:
BigDecimal a = new BigDecimal(String.valueOf(x));
BigDecimal b = new BigDecimal(y);

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

Categories

Resources