value one resolution unit smaller than another value?

Started by
19 comments, last by alvaro 15 years, 3 months ago
Hi and sorry for the not-so-clear subject text. Any idea what function can return me a floating value that is just a "tiny little bit" smaller than the floating value that I provided to the function? if v1 is the original value, then what is f(v1) that returns v2 which will always be: 1. v2<v1 2. v2==fmod(v2,v1) 3. v2+(any value bigger than 0)>=v1
Advertisement
You could make a function that does it.

float NextSmallestFloatValue( float value ){    return ( value - FLT_EPSILON );}
Thanks for your reply!

but.. wouldn't it rather be:

return(value*(1.0f-FLX_EPSILON));

?
Quote:Original post by floatingwoods
Thanks for your reply!

but.. wouldn't it rather be:

return(value*(1.0f-FLX_EPSILON));

?


I don't believe so.

Lets pretend FLT_EPSILON is something bigger just to make an example easier. Lets say FLT_EPSILON is 0.1f, and we'll say 'value' is 5.0f.

With your function
5.0f * ( 1.0f - 0.1f ) = 5.0f * 0.9f = 4.5f

With my example
5.0f - 0.1f = 4.9f

As you can see 4.9 is exactly 0.1 different from 5.0, and if 0.1 was the smallest possible float then you couldn't get any closer to 5.0 than 4.9 and still be smaller.
Lordikon,

Then try following:

float v1=1.0f;
float v2=1.0f-FLT_EPSILON;
if (v1==v2)
printf("Same!\n");

float v1=10000.0f;
float v2=10000.0f-FLT_EPSILON;
if (v1==v2)
printf("Same!\n");

Only the second paragraph will print out the message!
My best guess is that they floats are so close together that there may be some floating point inaccuracy. Try doing (2 * FLT_EPSILON) in the function in place of FLT_EPSILON, see what happens.
That's exactly the point: because floating-point values don't have a fixed precision, you get what you refer to as floating point inaccuracy!

But my question was: I need a value DIFFERENT from the original, but just slightly smaller. That's why I suggested:

value*(1.0f-FLT_EPSILON)

(with your method my two values would still be the same if original value is too big)
After testing, I found it is indeed it is floating point inaccuracy. Put a breakpoint on the line where 'float v2' is made, after you step over you'll see it remains 10000.000.

The inaccuracy happens because the float must represent 5 numbers to the left of the decimal, and three numbers to the right of the decimal place are closer to .000 then they are to .999, so it is rounded.

I'll try making a better example to explain this.
Quote:Original post by floatingwoods
That's exactly the point: because floating-point values don't have a fixed precision, you get what you refer to as floating point inaccuracy!

But my question was: I need a value DIFFERENT from the original, but just slightly smaller. That's why I suggested:

value*(1.0f-FLT_EPSILON)

(with your method my two values would still be the same if original value is too big)


Hmmm, I see what you mean. From you're first post I didn't get that I guess. That makes sense. That is why you said it must always work. The multiplication might work to avoid floating point inaccuracy, but I'm not sure it'd give you the next smallest value or not.
This is not really portable, but it will probably do what you want:
float previous(float x) {  int u = *reinterpret_cast<int *>(&x);  u--;  return *reinterpret_cast<float *>(&u);}

This topic is closed to new replies.

Advertisement