0

I am using the following two formulas to calculate upper and lower bounds given an expected result, a deviation and a deviation bound inserted by user:

public static Double getLowerBound(Double deviation,Double expectedValue,Float deviationBound){
    if(deviationBound == null || deviation == null || expectedValue == null)
        return null;

    int roundDigit = Math.max(getDecimalFloat(deviation.floatValue()), getDecimalFloat(expectedValue.floatValue()));
    Double valLowerBound = expectedValue - (deviationBound * deviation);
    String valLowerBoundStr = new BigDecimal(valLowerBound).setScale(roundDigit, BigDecimal.ROUND_HALF_UP).toString();
    return Double.valueOf(valLowerBoundStr);
}

public static Double getUpperBound(Double deviation,Double expectedValue,Float deviationBound){
    if(deviationBound == null || deviation == null || expectedValue == null)
        return null;

    int roundDigit = Math.max(getDecimalFloat(deviation), getDecimalFloat(expectedValue));
    Double valUpperBound = expectedValue + (deviationBound * deviation);
    String valUpperBoundStr = new BigDecimal(valUpperBound).setScale(roundDigit, BigDecimal.ROUND_HALF_UP).toString();
    return Double.valueOf(valUpperBoundStr);
}

where method getDecimalFloat() simply parses a float number and returns its digits after comma. Then, in another point of my code I have to apply and inverse formula to show deviation bound used before. So I do with:

public static Float getDeviationBound(Double deviation,Double expectedValue,Double lowerBound,Double upperBound){

    if(lowerBound == null || upperBound == null || deviation == null || expectedValue == null)
        return null;

    String ldb = new BigDecimal(Math.abs((lowerBound-expectedValue)/deviation)).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
    String udb = new BigDecimal(Math.abs((upperBound-expectedValue)/deviation)).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
    float lowerDeviationBound = Float.valueOf(ldb);
    float upperDeviationBound = Float.valueOf(udb);

    if(lowerDeviationBound == upperDeviationBound)
        return upperDeviationBound;

    return null;

}

Anyway, for some cases I get NULL back. Why this? For example, with a deviationBound = 3.5, expctedValue = 0.43, and lowerBound = 0.045 and upperBound = 0.81 it is not possible to apply an inverse formula. Which way is correct? I know that the problem is lowerDeviationBound is different from upperDeviationBound (3.5 vs 3.45) but I don’t know why this happens. Maybe because of some rounding politics of mine, I would like some advice if possible

SagittariusA
  • 5,289
  • 15
  • 73
  • 127
  • Clearly, `lowerDeviationBound != upperDeviationBound`. Debug it and find out why. – Bohemian Feb 07 '18 at 16:59
  • Yes, I know it’s that. Because I get 3.5 vs 3.45 but I don’t know why this happens, maybe a wrong rouding politics. I would like some advice on that – SagittariusA Feb 07 '18 at 17:02
  • See [ROUND_HALF_UP javadoc](https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html#ROUND_HALF_UP). Also, the calculation `(upperBound-expectedValue)/deviation` results in a `double`, which is an imprecise way to store data: Using `==` with doubles is a bad idea. Try something like `if (Math.abs(a-b) <= 0.0001)` instead – Bohemian Feb 07 '18 at 17:41
  • I had read javadoc for that param as it is the most common way to round numbers, just the one I am supposed to need. Anyway most of code I posted was written by someone else and I was asked to to some bug fixing. But why is it a bad idea to use == with doubles? I thought that double were much more precise than float. Moreover, with your solution in my case I would 0.05 which is not lower or equal than 0.0001 – SagittariusA Feb 07 '18 at 17:50
  • I meant to compare the *difference* between `(upperBound-expectedValue)/deviation` and (lowerBound-expectedValue)/deviation` with `0.00001`. You can't go via `BigDecimal` when comparing doubles. Further, `double` is just *less* imprecise the `float`, but they are both imprecise. Try writing the code without using `BigDecimal` – Bohemian Feb 07 '18 at 17:55
  • Ok, thank you mate. As soon as I come back at the office tomorrow I will try your code without BigDecimal. Is there a logic by which compare with 0.0001 than 0.001 or so on? – SagittariusA Feb 07 '18 at 17:58

0 Answers0