inimene
inimene

Reputation: 1650

What types to use for my numbers when calculating

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

Answers (3)

user4233758
user4233758

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

Adriaan Koster
Adriaan Koster

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

Cas Wolters
Cas Wolters

Reputation: 371

Try using float or double (preferred double because of the precision).

Upvotes: 1

Related Questions