Rounding up to 2 decimal place - java

I have this code below, my desired answer is 37.58 and not 37.56 or 37.60 after inputting 37576
BigDecimal n = new BigDecimal(num);
BigDecimal t = new BigDecimal(100);
BigDecimal res = n.divide(t);
BigDecimal b =res.setScale(1, BigDecimal.ROUND_HALF_UP);
DecimalFormat forma = new DecimalFormat("K0.00");
String bigf = forma.format(b);
txtnewk.setText(" " + bigf);
what changes do I have to make?

With the following code:
String num = "37576";
BigDecimal n = new BigDecimal(num);
BigDecimal t = new BigDecimal(1000);
BigDecimal res = n.divide(t);
BigDecimal b = res.setScale(2, BigDecimal.ROUND_HALF_UP);
b is 37.58 as desired.

Use this code for rounding numbers:
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;
}

You are using wrong version of divide (if you are rounding it immediately). Value of setScale is wrong. You should have:
BigDecimal res = n.divide(t, 2, BigDecimal.ROUND_HALF_UP);

Using double you can do
long l = 37576; // or Long.parseLong(text);
double v = Math.round(l / 10.0) / 100.0;
System.out.println(v);
prints
37.58
The first rounded / 10.0 says you want to drop the lowest digit by rounding and the / 100.0 says you want to shift the decimal place by two digits.

Related

How can I get only the decimal value of a number and I will store that value into another variable using Java? [duplicate]

I have a double variable d = 1.15.
I want the number after the decimal point, i.e. "15".
What is best way to achieve this in Java?
I have tried like this:
Double d = 1.15;
String str = d.toString();
int len = str.substring(str.indexOf(".")).length() - 1;
int i= (int) (d * (long)Math.pow(10,len) % (long)Math.pow(10,len));
But I didn't get the proper answer because when I convert d.toString() the answer is 14.999999999999986.
Try this:
String numberD = String.valueOf(d);
numberD = numberD.substring(numberD.indexOf("."));
Now this numberD variable will have value of 15
Try Math.floor();
double d = 4.24;
System.out.println( d - Math.floor( d ));
To prevent rounding errors you could convert them to BigDecimal
double d = 4.24;
BigDecimal bd = new BigDecimal( d - Math.floor( d ));
bd = bd.setScale(4,RoundingMode.HALF_DOWN);
System.out.println( bd.toString() );
Prints 0.2400
Note that the 4 in setScale is the number of digits after the decimal separator ('.')
To have the remainder as an integer value you could modify this to
BigDecimal bd = new BigDecimal(( d - Math.floor( d )) * 100 );
bd = bd.setScale(4,RoundingMode.HALF_DOWN);
System.out.println( bd.intValue() );
Prints 24
The number after the decimal point is not a well defined concept. For example for "4.24", it could be "0.24", "0.239999999999" (or similar), "24" or "239999999999".
You need to be clear if you are talking about a number or a string of decimal digits ... and whether the input value is a representation of a binary floating point number (in which case "4.24" is most likely an approximation) a decimal floating point number.
Depending on your interpretation, the correct answer will be different.
But i didn't get the proper answer because when I converted d.toString() the answer is 14.999999999999986.
You are running up against the problem that double and float are base-2 floating point formats, and in most cases they CANNOT represent decimal floating point numbers precisely. There is no fix for this ... apart from using something like BigDecimal to represent your numbers. (And even then, some loss of precision is possible whenever you do a division or modulo operation.)
Try out RegEx, here ^\d*\., will search for digits followed by dot and replace with blank.
for(double d : new double[]{1.15,0.009,222.9,3.67434}){
System.out.println(String.valueOf(d).replaceAll("^\\d*\\.",""));
}
gives:
15
009
9
67434
If you want the decimal places and you want to round the result.
double d = 4.24;
System.out.printf("%0.2f%n", d - (long) d);
prints
0.24
If you want a rounded value, you have to determine what precision you want.
double d = 4.24;
double fract = d - (long) d;
fract = (long) (fract * 1e9 + 0.5) / 1e9; // round to the 9 decimal places.
If your double is:
d = 1.25;
And if you do this:
String number = String.valueOf(d);
number = number.substring(number.indexOf(".")).substring(1);
then number will be 25.
I don't know if this is the best way to do this, but it works.
Have you tried d = d%1.0? That should return the remainder of dividing d by 1, which should just be the decimal portion.
You could also do this to get the value as an int: d = (int)((d%1.0)*100)
Instead of d.toString(), try this:
String str = String.format("%.2f", d);
Just as in any other language: multiply by 10 and check the int part of remnant when dividing by 10. The same way you would extract digits from an integer.
short[] digits = new short[max_len];
double tmp = d - ((int) d);
for (int i = 0; i < digits.length && tmp != 0; i++)
{
tmp *= 10;
digit[i] = (short) tmp;
tmp -= (int) tmp;
}
But be aware that for double you need to introduce a precision limit - the maximum number of digits to extract (max_len from the code sample above).
Slight update (added rounding at the edge of precision):
double d = 1.15;
short[] digits = new short[10];
double tmp = d - ((int) d) + 0.5 * 1e-10;
for (int i = 0; i < digits.length && tmp != 0; i++)
{
tmp *= 10;
digits[i] = (short) tmp;
tmp -= (int) tmp;
}
double d = 4.24;
d = (d - Math.floor( d ));
int e = (int)(Math.round(d*100));
System.out.println(e);
Yields 24
Scanner scr= new Scanner (System.in);
double d= scr.nextDouble();
BigDecimal bc= new BigDecimal ((d - Math.floor(d))*1e5);
bc=bc.setScale(4,RoundingMode.HALF_DOWN);
double f = bc.doubleValue();
while(f%10==0)
{
f=f/10;
}
System.out.println(f);
try this :
double d = 1.1512;
int i = (int) (d*100 - Math.floor(d)*100);
now this will give you : 15
ExAMPLE :
Double d = 469.951479;
String string = d.toString();
char[] len = string.substring(string.indexOf(".")).toCharArray();
System.out.println(len);
double myNumber = 1.15;
//numbers After Dot
double n = 2;
double right_of_dot = (myNumber - (int) myNumber)*Math.pow(10,n);
Try this:
var decimalsOnly = (parseFloat(decNum)-parseInt(decNum,10)).toFoxed(2);

Rounding in java shows different result [duplicate]

I tried the following,
double doubleVal = 1.745;
double doubleVal1 = 0.745;
BigDecimal bdTest = new BigDecimal( doubleVal);
BigDecimal bdTest1 = new BigDecimal( doubleVal1 );
bdTest = bdTest.setScale(2, BigDecimal.ROUND_HALF_UP);
bdTest1 = bdTest1.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("bdTest:"+bdTest); //1.75
System.out.println("bdTest1:"+bdTest1);//0.74 problemmmm ????????????
but got weird results. Why?
Never construct BigDecimals from floats or doubles. Construct them from ints or strings. floats and doubles loose precision.
This code works as expected (I just changed the type from double to String):
public static void main(String[] args) {
String doubleVal = "1.745";
String doubleVal1 = "0.745";
BigDecimal bdTest = new BigDecimal( doubleVal);
BigDecimal bdTest1 = new BigDecimal( doubleVal1 );
bdTest = bdTest.setScale(2, BigDecimal.ROUND_HALF_UP);
bdTest1 = bdTest1.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("bdTest:"+bdTest); //1.75
System.out.println("bdTest1:"+bdTest1);//0.75, no problem
}
double doubleVal = 1.745;
double doubleVal1 = 0.745;
System.out.println(new BigDecimal(doubleVal));
System.out.println(new BigDecimal(doubleVal1));
outputs:
1.74500000000000010658141036401502788066864013671875
0.74499999999999999555910790149937383830547332763671875
Which shows the real value of the two doubles and explains the result you get. As pointed out by others, don't use the double constructor (apart from the specific case where you want to see the actual value of a double).
More about double precision:
here
there
Use BigDecimal.valueOf(double d) instead of new BigDecimal(double d). The last one has precision errors by float and double.
This will maybe give you a hint on what went wrong.
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
BigDecimal bdTest = new BigDecimal(0.745);
BigDecimal bdTest1 = new BigDecimal("0.745");
bdTest = bdTest.setScale(2, BigDecimal.ROUND_HALF_UP);
bdTest1 = bdTest1.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("bdTest:" + bdTest); // prints "bdTest:0.74"
System.out.println("bdTest1:" + bdTest1); // prints "bdTest:0.75"
}
}
The problem is, that your input (a double x=0.745;) can not represent 0.745 exactly. It actually saves a value slightly lower. For BigDecimals, this is already below 0.745, so it rounds down...
Try not to use the BigDecimal(double/float) constructors.
For your interest, to do the same with double
double doubleVal = 1.745;
double doubleVal2 = 0.745;
doubleVal = Math.round(doubleVal * 100 + 0.005) / 100.0;
doubleVal2 = Math.round(doubleVal2 * 100 + 0.005) / 100.0;
System.out.println("bdTest: " + doubleVal); //1.75
System.out.println("bdTest1: " + doubleVal2);//0.75
or just
double doubleVal = 1.745;
double doubleVal2 = 0.745;
System.out.printf("bdTest: %.2f%n", doubleVal);
System.out.printf("bdTest1: %.2f%n", doubleVal2);
both print
bdTest: 1.75
bdTest1: 0.75
I prefer to keep code as simple as possible. ;)
As #mshutov notes, you need to add a little more to ensure that a half value always rounds up. This is because numbers like 265.335 are a little less than they appear.
various option are available such as:
Double d= 123.12;
BigDecimal b = new BigDecimal(d, MathContext.DECIMAL64); // b = 123.1200000
b = b.setScale(2, BigDecimal.ROUND_HALF_UP); // b = 123.12
BigDecimal b1 =new BigDecimal(collectionFileData.getAmount(), MathContext.DECIMAL64).setScale(2, BigDecimal.ROUND_HALF_UP) // b1= 123.12
d = (double) Math.round(d * 100) / 100;
BigDecimal b2 = new BigDecimal(d.toString()); // b2= 123.12

Remove unnecessary rounding

How do I get the correct not rounded result as what I get in excel?
public void testdivide_largenumber() {
double result;
double number = 8789700;
double divisor = 3200;
BigDecimal number_BD = new BigDecimal(number, MathContext.DECIMAL64);
BigDecimal divisor_BD = new BigDecimal(divisor, MathContext.DECIMAL64);
BigDecimal result_BD;
result = (double) (number / divisor);
result_BD = number_BD.divide(divisor_BD);
System.out.println("double result should be 2746.78124999656="+ result );
System.out.println("BigDecimal result should be 2746.78124999656="+ result_BD );
}
Result:
double result should be 2746.78124999656=2746.78125
BigDecimal result should be 2746.78124999656=2746.78125
As #Lino pointed out in his comment, 8789700/3200 = 2746.78125. The result that you got from excel has floating point rounding errors, java is correct.

Non-Terminating Decimal Error Even With MathContext

I'm crafting code to implement this algorithm:
However, I'm getting this error, even with MathContext(1000):
Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
at java.math.BigDecimal.divide(BigDecimal.java:1603)
at picalculator.PiCalculator.calculatePi(PiCalculator.java:59)
at picalculator.PiCalculator.main(PiCalculator.java:25)
Java Result: 1
While using this method:
public static void calculatePi() {
BigInteger firstFactorial;
BigInteger secondFactorial;
BigInteger firstMultiplication;
BigInteger firstExponent;
BigInteger secondExponent;
int firstNumber = 1103;
BigInteger firstAddition;
BigDecimal currentPi = BigDecimal.ONE;
BigDecimal pi = BigDecimal.ONE;
BigDecimal one = BigDecimal.ONE;
int secondNumber = 2;
double thirdNumber = Math.sqrt(2.0);
int fourthNumber = 9801;
BigDecimal prefix = BigDecimal.ONE;
for(int i=1;i<4;i++){
firstFactorial = factorial(4*i);
secondFactorial = factorial(i);
firstMultiplication = BigInteger.valueOf(26390*i);
firstExponent = exponent(secondFactorial, 4);
secondExponent = exponent(BigInteger.valueOf(396),4*i);
firstAddition = BigInteger.valueOf(firstNumber).add(firstMultiplication);
currentPi = currentPi.add(new BigDecimal(firstFactorial.multiply(firstAddition)).divide(new BigDecimal(firstExponent.multiply(secondExponent)), new MathContext(10000)));
}
prefix =new BigDecimal(secondNumber*thirdNumber);
prefix = prefix.divide(new BigDecimal(fourthNumber), new MathContext(1000));
currentPi = currentPi.multiply(prefix, new MathContext(1000));
pi = one.divide(currentPi);
System.out.println("Pi is: " + pi);
return;
}
I have proven that factorial(a); and exponent(a,b) return the factorial of a and the result of a^b respectively, accurately.
Does anyone know how to fix this?
You need
pi = one.divide(currentPi, new MathContext(1000));
Since the result is almost certainly a repeating decimal.
Consider
BigDecimal a = new BigDecimal("4");
BigDecimal b = new BigDecimal("3");
BigDecimal c = a.divide(b) // java.lang.ArithmeticException: Non-terminating decimal expansion
BigDecimal c = a.divide(b, new MathContext(10)); // No exception
You might prefer to use different version of divide. It gives you more control over the final scale of the returned BigDecimal. Whereas, with your version the final scale depends on the scale of the dividend and divisor.
int scale = 3;
BigDecimal result = ONE.divide(new BigDecimal("3"), scale, RoundingMode.HALF_UP);
// result is 0.333

How do I get the part after the decimal point in Java?

I have a double variable d = 1.15.
I want the number after the decimal point, i.e. "15".
What is best way to achieve this in Java?
I have tried like this:
Double d = 1.15;
String str = d.toString();
int len = str.substring(str.indexOf(".")).length() - 1;
int i= (int) (d * (long)Math.pow(10,len) % (long)Math.pow(10,len));
But I didn't get the proper answer because when I convert d.toString() the answer is 14.999999999999986.
Try this:
String numberD = String.valueOf(d);
numberD = numberD.substring(numberD.indexOf("."));
Now this numberD variable will have value of 15
Try Math.floor();
double d = 4.24;
System.out.println( d - Math.floor( d ));
To prevent rounding errors you could convert them to BigDecimal
double d = 4.24;
BigDecimal bd = new BigDecimal( d - Math.floor( d ));
bd = bd.setScale(4,RoundingMode.HALF_DOWN);
System.out.println( bd.toString() );
Prints 0.2400
Note that the 4 in setScale is the number of digits after the decimal separator ('.')
To have the remainder as an integer value you could modify this to
BigDecimal bd = new BigDecimal(( d - Math.floor( d )) * 100 );
bd = bd.setScale(4,RoundingMode.HALF_DOWN);
System.out.println( bd.intValue() );
Prints 24
The number after the decimal point is not a well defined concept. For example for "4.24", it could be "0.24", "0.239999999999" (or similar), "24" or "239999999999".
You need to be clear if you are talking about a number or a string of decimal digits ... and whether the input value is a representation of a binary floating point number (in which case "4.24" is most likely an approximation) a decimal floating point number.
Depending on your interpretation, the correct answer will be different.
But i didn't get the proper answer because when I converted d.toString() the answer is 14.999999999999986.
You are running up against the problem that double and float are base-2 floating point formats, and in most cases they CANNOT represent decimal floating point numbers precisely. There is no fix for this ... apart from using something like BigDecimal to represent your numbers. (And even then, some loss of precision is possible whenever you do a division or modulo operation.)
Try out RegEx, here ^\d*\., will search for digits followed by dot and replace with blank.
for(double d : new double[]{1.15,0.009,222.9,3.67434}){
System.out.println(String.valueOf(d).replaceAll("^\\d*\\.",""));
}
gives:
15
009
9
67434
If you want the decimal places and you want to round the result.
double d = 4.24;
System.out.printf("%0.2f%n", d - (long) d);
prints
0.24
If you want a rounded value, you have to determine what precision you want.
double d = 4.24;
double fract = d - (long) d;
fract = (long) (fract * 1e9 + 0.5) / 1e9; // round to the 9 decimal places.
If your double is:
d = 1.25;
And if you do this:
String number = String.valueOf(d);
number = number.substring(number.indexOf(".")).substring(1);
then number will be 25.
I don't know if this is the best way to do this, but it works.
Have you tried d = d%1.0? That should return the remainder of dividing d by 1, which should just be the decimal portion.
You could also do this to get the value as an int: d = (int)((d%1.0)*100)
Instead of d.toString(), try this:
String str = String.format("%.2f", d);
Just as in any other language: multiply by 10 and check the int part of remnant when dividing by 10. The same way you would extract digits from an integer.
short[] digits = new short[max_len];
double tmp = d - ((int) d);
for (int i = 0; i < digits.length && tmp != 0; i++)
{
tmp *= 10;
digit[i] = (short) tmp;
tmp -= (int) tmp;
}
But be aware that for double you need to introduce a precision limit - the maximum number of digits to extract (max_len from the code sample above).
Slight update (added rounding at the edge of precision):
double d = 1.15;
short[] digits = new short[10];
double tmp = d - ((int) d) + 0.5 * 1e-10;
for (int i = 0; i < digits.length && tmp != 0; i++)
{
tmp *= 10;
digits[i] = (short) tmp;
tmp -= (int) tmp;
}
double d = 4.24;
d = (d - Math.floor( d ));
int e = (int)(Math.round(d*100));
System.out.println(e);
Yields 24
Scanner scr= new Scanner (System.in);
double d= scr.nextDouble();
BigDecimal bc= new BigDecimal ((d - Math.floor(d))*1e5);
bc=bc.setScale(4,RoundingMode.HALF_DOWN);
double f = bc.doubleValue();
while(f%10==0)
{
f=f/10;
}
System.out.println(f);
try this :
double d = 1.1512;
int i = (int) (d*100 - Math.floor(d)*100);
now this will give you : 15
ExAMPLE :
Double d = 469.951479;
String string = d.toString();
char[] len = string.substring(string.indexOf(".")).toCharArray();
System.out.println(len);
double myNumber = 1.15;
//numbers After Dot
double n = 2;
double right_of_dot = (myNumber - (int) myNumber)*Math.pow(10,n);
Try this:
var decimalsOnly = (parseFloat(decNum)-parseInt(decNum,10)).toFoxed(2);

Categories

Resources