If you read about floating point arithmetic, you'll soon find that using equality or inequality tests to compare two floating point values is strongly discouraged.
This is because floating point values have a high precision, and two values that would seem equal to us may not be exactly equals.
So you have to resort to things like this
|
if( fabs(fp1 - fp2) <= EPS ) // instead of if( fp1 == fp2 )
|
where EPS is the maximal distance under which you consider two numbers to be equal.
In your case, you have two values : the one you think you entered, and the one that is really stored, which is slightly off.
EPS is a kind of upper bound of the distance between the 2 values.
As for the rounding, it's simple :
If you have two numbers x and y, computing y*round(x/y) gives you the multiple of y nearest to x.
Let's choose an EPS that divides the wanted value of b.
Computing EPS*round(wanted_value/EPS) will give wanted_value.
Computing EPS*round(stored_value/EPS) will give the multiple of EPS nearest to stored_value.
If the distance between the wanted value and the stored value is small enough compared to EPS (ie smaller than EPS/2), the nearest multiple of EPS will be the wanted value.
So, by rounding, we eliminated the error.
My choice of EPS:
Since your value is a finite decimal number, I figured that a sufficiently small power of 10 would always divide it.
In your examples, the error was always around 1e-12.
Taking 1e-10 seemed a good choice.
Your choice of EPS:
The trick with floating point values is that the error is proportional to the value stored.
The best choice of EPS would be to compute it proportional to b.
For example, if you know you will not have more than N significant digits in your number, you could try something like EPS = b*1e-(N+1);