C++'s floats not very good?

Started by
27 comments, last by SiCrane 13 years, 4 months ago
To add to the collection of useful references on the topic...

I also would highly recommend Chapter 11, "Numerical Robustness" of Christer Ericson's Real-Time Collision Detection for a brief, but very useful and practical look at the topic. The chapter is only 40 pages and is still very effective (which is impressively concise given the potential size of the topic).

(Here's a link to the book on amazon: http://www.amazon.com/Real-Time-Collision-Detection-Interactive-Technology/dp/1558607323)
Advertisement
Quote:Original post by Ravyne
[...] I'm not sure of the exact difference, but I'd wager its 10s of orders of magnitude larger than the difference between the smallest representable numbers. [...]


If you want a showpiece for that, assign 20,000,000 (20 million) to a (32 bit) floating point variable.

The next larger number the floating point variable can assume is 20,000,002 - that's 2 full digits, not decimal places.

This "smallest possible increment" has been dubbed "Unit in the Last Place", or "ULP" for short (Wikipedia has an article on it). So while 20,000,000 + 1 ULP = 20,000,002 but 1.0 + 1 ULP = 1.00000012. There's some code floating around which can tell you how many ULPs two floating point numbers are apart, which is a good way to compare floating points without using fixed epsilon values (no idea how it compares to Prune's method or if its results would be identical give the right epsilon value).
Professional C++ and .NET developer trying to break into indie game development.
Follow my progress: http://blog.nuclex-games.com/ or Twitter - Topics: Ogre3D, Blender, game architecture tips & code snippets.
Quote:Original post by Prune
Quote:
if(floatVar == 0.795)
You have to use the infinitely more complex:
if((floatVar >= 0.795f) && (floatVar < 0.910))

Faster, and less arbitrary:
float temp(floatVar - 0.795f);
if (temp * temp < std::numeric_limits<float>::min())


A multiplication (with dependency chain) is not faster than a float compare.

Quote:I swear to gawd that a computer architecture course should be an absolute requirement before any programming course in an accredited CS program


Quite.

Using your method....

float a = 1.000000001e28f;float b = 1.000000000e28f;float temp = a - b;if( (temp * temp) < 1.175494351e-38f /* aka FLT_MIN */ ){  /* How often will you get here? */}


The == operator does the same thing as that code, but cheaper......

Quote:Depending on the mathematical operations used to reach the value of the variables, you might need to compare to numeric_limits<float>::epsilon() or a multiple thereof instead.


Either an *extremely* large multiple, or find a better solution.... (of which there are many).
Oh woah, okay.
I had a subject at University about internal computer systems and all that, floating point wasn't covered in any depth. Nor was it covered in any of my programming subjects, which is annoying.
Would I be better of using something like short? Or are they performed in a similar manner, just with less bits?
Quote:Original post by Nauraushaun
Would I be better of using something like short? Or are they performed in a similar manner, just with less bits?


short is an integer type. You can represent all integers (up to 2^bitsize of the type) with any integer type.

If you want real-type numbers x.xxxxx or whatever, you need to use float or double and do epsilon comparisons. It's really not a big deal, the only real sacrifice you have to use is making those comparisons if ( x >= number-epsilon && x <= number+epsilon) instead of if ( x == number )

-me
Quote:Original post by Nauraushaun
Would I be better of using something like short? Or are they performed in a similar manner, just with less bits?
Better off in what way? You should use the data type that is most appropriate for what you want to use it for.

If you need fractional data your options are float/double, aribtrary precision arithmetic library, or fixed-point arithmetic. If you don't need fractional data use one of the existing built-in integer types of which short is a possible choice.

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!

Oh, yeah, for some reason I was thinking a short was a floating point number with less digits. How silly of me, that's completely wrong.
But yeah, I'm set. Thanks everyone for your help.

You can also do a branching compare though it is likely to be slower than what has already been proposed.

inline bool compareFloats (float a, float b){	return (abs(a - b) < EPSILON);}
Quote:Original post by Ameise
You can also do a branching compare though it is likely to be slower than what has already been proposed.

inline bool compareFloats (float a, float b){	return (abs(a - b) < EPSILON);}


Erm, what's been proposed is branching comparisons, as far as I can tell. What suggestions are you referring to that don't involve a branch?


(BTW this is a trick question. All comparisons in this sense (i.e. executing code depending on a value) are branches [wink])

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Quote:Original post by ApochPiQ
Quote:Original post by Ameise
You can also do a branching compare though it is likely to be slower than what has already been proposed.

inline bool compareFloats (float a, float b){	return (abs(a - b) < EPSILON);}


Erm, what's been proposed is branching comparisons, as far as I can tell. What suggestions are you referring to that don't involve a branch?


(BTW this is a trick question. All comparisons in this sense (i.e. executing code depending on a value) are branches [wink])


Apologies, I wrote this late at night whilst getting out of work. :D

They differ in mechanism to actually compare the two floats - everyone else's methods rely on a range-test between two floats while mine relies on the absolute value of the difference - depending on how abs is implemented, I would imagine that mine involves two branches.

This topic is closed to new replies.

Advertisement