Reputation: 1650
So I need to calculate a value.
The input I get is this:
a is seed/m2. The value might a for example 56 but it might be 56.7 also.
b is in g's. for instance 600g
c is % value, might be 90.6 also
d is % value, might be 90.6 also
The result I get should be as kg/ha
Regular int does not cut it. The value of (56 * 600 / 100 / 100) / 100
will be 0.0336
. I could multiply it with 10000 but I would lose the precision.
I also tried BigDecimal for this but it gave me a ArithmeticException: “Non-terminating decimal expansion; no exact representable decimal result”
when I changed the values of my % variables to something else than 100.
What would be the best option to go with this? The calculation was easy to do in exel as it knew how to convert each value automatically, but doing it in Java code is another thing.
My solutions:
int version:
int a = Integer.decode(germinativeSeed.getText().toString());
int b = Integer.decode(seedMass.getText().toString());
int c = Integer.decode(clean.getText().toString());
int d = Integer.decode(germinative.getText().toString());
int result2 = ( a * b / c / d) / 100;
result is 0
BigDecimal solution:
BigDecimal result2;
BigDecimal a = new BigDecimal(germinativeSeed.getText().toString());
BigDecimal b = new BigDecimal(seedMass.getText().toString());
BigDecimal c;
BigDecimal d;
if (clean.getText().toString().equals("")) {
c = new BigDecimal("100");
} else {
c = new BigDecimal(clean.getText().toString());
}
if (germinative.getText().toString().equals("")) {
d = new BigDecimal("100");
} else {
d = new BigDecimal(germinative.getText().toString());
}
BigDecimal hundred = new BigDecimal("100");
BigDecimal test = new BigDecimal("10000");
result2 = a.multiply(b);
result2 = result2.divide(c, 2, RoundingMode.HALF_UP);
result2 = result2.divide(d, 2, RoundingMode.HALF_UP);
result2 = result2.divide(hundred, 2, RoundingMode.HALF_UP);
result2 = result2.multiply(test);
Result is correct with this only if % values are 100%.
Upvotes: 3
Views: 81
Reputation:
Your problem comes when you have rational numbers like 1/3, this cannot be represented in a bigdecimal, as it has an infinite representation.
If you really need very big precision you should crate a new bigrational class, where you would store a nominator and denominator, and calculate with them. The code would be much mode complicated.
If you don't need that go for doubles.
Upvotes: 2
Reputation: 16209
double seed = (double) seedInput;
double m2 = (double) m2Input;
double b = (double) bInput; // unit 'g' is not relevant
double c = (double) cInput;
double d = (double) dInput;
double a = seed / m2;
int result2 = ( a * b / c / d) / 100.0;
So I converted everything to double so you won't have problems with implicit conversions to int.
Upvotes: 3
Reputation: 371
Try using float
or double
(preferred double
because of the precision).
Upvotes: 1