Reputation: 1
I can see that there are hundreds of posts on the subject of rounding decimal places. However, I have searched high and low and cannot seem to find a previous instance that matches my problem. I am pretty new to java.
I am trying to calculate the slope of a line, assign it to a variable and have the contents of that variable be formatted to 4 decimal places.
I have tried DecimalFormat (appears to return a string, I need a numerical value that can be used in another stage of calculations)
I have tried BigDecimal (cannot seem to figure out how to construct it and setScale).
Below is my code:
import java.math.BigDecimal;
public class Scratch {
public static void main(String[] args) throws Exception {
BigDecimal slope1, slope2, slope3;
slope1 = new BigDecimal((8 - 8) / (20 - 5));
slope2 = new BigDecimal((9 - 8) / (22 - 5));
slope3 = new BigDecimal((9 - 8) / (22 - 20));
slope1 = slope1.setScale(4);
slope2 = slope1.setScale(4);
slope3 = slope1.setScale(4);
System.out.println(slope1);
System.out.println(slope2);
System.out.println(slope3);
}
}
The resulting output is:
0.0000
0.0000
0.0000
How to I construct the big data object, set it's scale, and do the calculation in a way that will give the real result of the calculation to 4 decimal places and not 0.0000?
Any help would be greatly appreciated. I've been messing with this for hours.
Upvotes: 0
Views: 427
Reputation: 10955
You've got two problems here.
The first is that you are using integer arithmetic in the constructor of your BigDecimal
s.
You can fix this by casting the value to double.
Your second problem is that you are setting the scale of slope1
three times, and ignoring the values of slope2
and slope3
here:
slope1 = slope1.setScale(4);
slope2 = slope1.setScale(4); // should be slope2
slope3 = slope1.setScale(4); // should be slope3
However, when you fix this, you'll get an ArithmeticException
when you try to calculate slope2
. Whenever you use scale()
to round a number, you need to specify a RoundingMode
so that it knows how you want to round.
Try this:
slope1 = new BigDecimal((double) (8 - 8) / (20 - 5));
slope2 = new BigDecimal((double) (9 - 8) / (22 - 5));
slope3 = new BigDecimal((double) (9 - 8) / (22 - 20));
slope1 = slope1.setScale(4, RoundingMode.HALF_UP);
slope2 = slope2.setScale(4, RoundingMode.HALF_UP);
slope3 = slope3.setScale(4, RoundingMode.HALF_UP);
System.out.println(slope1); // 0.0000
System.out.println(slope2); // 0.0588
System.out.println(slope3); // 0.5000
Upvotes: 3
Reputation: 5937
Integer arithmetic is all whole numbers.
slope1 = new BigDecimal((8d - 8d) / (20d - 5d));
slope2 = new BigDecimal((9d - 8d) / (22d - 5d));
slope3 = new BigDecimal((9d - 8d) / (22d - 20d));
To just make your code work, append d for double. Basically what's happening is all your numbers are considered integers, and performing integer map does such magic as 9 / 8 evaluates to 1. Other alternatives include hard-casting with decimals or casting the combined values to double.
slope2 = new BigDecimal((9.0 - 8.0) / (22.0 - 5.0));
or
slope2 = new BigDecimal((double) (9 - 8) / (double) (22 - 5));
Upvotes: 1
Reputation: 685
change
slope1 = new BigDecimal((8 - 8) / (20 - 5));
to
slope1 = new BigDecimal(((double)8 - 8) / ((double)20 - 5));
Upvotes: 0
Reputation: 26990
What is really the problem here is int arithmetic:
(9 - 8) / (20 - 5)
is equal to 1 / 15
which in int arithmetic is equal to 0
.
To get the right result you have to enforce double arithmetic by making at least one of the numbers double
:
((double)(9 - 8) / (20 - 5))
or ((9.0 - 8) / (20 - 5))
Upvotes: 0