4

I need to keep the granularity in a fuzzy job so I made a function which receives as parameters:

  • the granularity (a double between 0 and 1, 0 not included)
  • the value to transform, if necessary (it's a double greater than 0)

And returns a new value with the correct granularity.

This is the function I have:

public static double preserveGranularity(double granul, double value){
    double integerValue= (double)(int)value;
    if(granul == 1)
        return integerValue;
    double decimal = value - integerValue;
    long factor = Math.round(decimal/granul);
    return integerValue + granul*factor;
}

Examples:

  • preserveGranularity(0.25, 7.7) should return 7.75
  • preserveGranularity(0.01, 0.009) should return 0.01

It runs good for most of values, but it doesn't for all (e.g.: preserveGranularity(0.2, 0.57)=0.6000000000000001, it should return 0.6)

Regards

P.S. Sorry for any mistake I made in this question, it's my first one here

2 Answers2

4

You cannot achieve this with double - since it is not exact enough.
doubles are not real numbers. There are only finite number of bits to represent them - while there are infinite number of real (or even rational) numbers out there, so these rounding errors are expected.

I think you are looking for BigDecimal, which lets you control the granularity, as you want, for example with its round() method.

amit
  • 175,853
  • 27
  • 231
  • 333
1

Floating point calculations are not exact (the computer can only represent so much digits). This means that somewhere in your division/multiplication/rounding/subtraction/addition operations you lose precision.

Attila
  • 28,265
  • 3
  • 46
  • 55