Sign in to follow this  

float vs int arithmetic - should I even bother?

This topic is 2542 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've looked up a little bit on this topic but I can't find a straight answer. Floats are pretty convenient for a game. I like using them, but the more arithmetic I keep putting into my project the more I wonder if I should be doing this math with ints instead.

I searched this forum, and saw a few posts say "just use floats". Can anyone give more insight if this issue should even be bothered with? Or if it is something to mind, at what point would it start to matter?

Share this post


Link to post
Share on other sites
Depends entirely on what you're doing.


There are places where int-centered designs (including fixed point designs) are far superior to floating point, such as when you're working with a narrow, known value range and need high precision in all circumstances. However, there are rarely cases where a double-precision IEEE float (aka. a double in most languages) can't do a perfectly reasonable job.

There are also cases where interleaving integer and floating point operations can lead to slightly faster code, but this is black magic and almost certainly not relevant for 99.9% of optimization situations.


So, in total: just use floats. Be aware of the precision and limited-representation issues inherent in floating point arithmetic, but unless you know you'll run afoul of them due to the nature of your program, you can safely design around them almost all of the time.

If you really, really, really need it, there exist some fantastic arbitrary-precision numeric libraries out there for various platforms. Just be warned that they aren't nearly as fast as the "built-in" arithmetic running straight off the CPU.

Share this post


Link to post
Share on other sites
The problem with using ints as decimals is that while you get a much higher accurate range, you have to constantly be on the lookout for overflow, which will break your program. You hardly need to worry about this at all with floats.

Floats often allow you to ignore divide by zero and certain 0/0 situations in cases where the presence of a zero denominator is a perfectly valid program state. With integers you aren't allowed to divide by zero at all, and need to handle it as a special case.
This behaviour is easier to debug with floats because +/- infinity and NaN values propagate in subsequent operations. You can look at the output of a complicated series of operations and immediately see that a divide by zero has occurred.

Share this post


Link to post
Share on other sites
This is a bit of a pet-peeve of mine, so be warned; I think floats are WAY overrated.

They have many perfectly legit uses, but simply using them whenever you dont want an integer is just bad design.

For instance; floats are generally the right tool for the job for relative measurements, where the importance of accuracy varies with distance.

They are generally an aweful tool for absolute measurements, such as positions in a global coordinate system. Just think about it: the sub planck-scale precision you get around the origin is a complete waste for ANY application. Since a 32bit float has just as many states as a 32bit int, you are going to pay for it somewhere. Your simulation may not overflow with a spaceship somewhere at e50 away from the origin, but will nonetheless be completely and horribly broken with the resolution measured in lightyears you are getting at that point.

By contrast; a 32bit int will give you uniform micron precision over a 4km region. A 64bit int will cover a lightyear in good precision. Those are very reasonable constraints for any application I can think of.

By contrast again, a 32bit float and its 7 significant decimal places is down to a trippy 2cm precision scale at 2km distance from the origin (not even counting the horrors introduced by actually performing operations on these numbers); yay, its not overflowing, but id rather get my bugs and artifacts thrown in my face so I can correct them before I ship. Maybe you dont need two kilometers, but who doesnt need a 100m? Well, you had better get used to your physics simulation making your objects jitter around at millimeter scale then.

I wouldnt bother with ints for performance, although I like the fact that you dont need any casts to do spatial (hash)mapping.

That said, working with ints is somewhat trickier. Taking products of ints requires the result to have double the bits; the result of two 64bit multiples requires 128bit storage; though these are only used as intermediary values, typically.

It may pay to do some thinking about whether to go with floats or ints. 64bit floats are generally a safe although perhaps suboptimal bet; 32bit floats are simply not up to many of the tasks they are routinely used for.

Share this post


Link to post
Share on other sites
There are places where floats are a good idea and places where they aren't.

For all graphics, even 2D, you usually want to use floats, especially if you're going to have advanced 2D effects such as matrix transformations and pixel shaders. For 3D it's floats always. Besides, the graphic libraries like DirectX and OpenGL take floating-point values anyway.

There are places where it's not a good idea. Like currency. You could use a float if you need fractions of a cent but if you're just storing prices, convert it to cents and store an integer.

And it's pretty obvious you don't use a float in a for loop and most other basic things.

I mean 32-bit floats though. I don't think I've ever encountered a situation where I needed the precision of a 64-bit or 80-bit float and I don't think I ever will. Those are probably used in advanced scientific, engineering or financial fields.

Share this post


Link to post
Share on other sites
Quote:
Original post by Bearhugger
I mean 32-bit floats though. I don't think I've ever encountered a situation where I needed the precision of a 64-bit or 80-bit float and I don't think I ever will. Those are probably used in advanced scientific, engineering or financial fields.
Planet/solar system/galaxy rendering. We have to use 128-bit integers, in a hierarchical coordinate system, which are munged into doubles for local calculations, then munged into floats for the GPU...

Share this post


Link to post
Share on other sites
About floats vs. doubles.

The accuracy of intermediate results of calculations can matter to the user as any error on one step of the calculation will pass on to the next step of the calculation and the more steps the calculation has the more likely it is that the final result has significant error.

So to improve accuracy of the intermediate steps you can use doubles when you calculate something even when the final result must be passed on as a float and this can give you a better end result.

So rejecting doubles simply on the basis that the final result of a calculation must be passed on as a float to an API is not necessarily a good thing to do.

Share this post


Link to post
Share on other sites
Quote:
Original post by reptor
So rejecting doubles simply on the basis that the final result of a calculation must be passed on as a float to an API is not necessarily a good thing to do.


Exactly; the same is true of ints. Which undermines the whole premise of bearhuggers' post.

Share this post


Link to post
Share on other sites
Quote:
Original post by reptor
The accuracy of intermediate results of calculations can matter to the user as any error on one step of the calculation will pass on to the next step of the calculation and the more steps the calculation has the more likely it is that the final result has significant error.

So to improve accuracy of the intermediate steps you can use doubles when you calculate something even when the final result must be passed on as a float and this can give you a better end result.

So rejecting doubles simply on the basis that the final result of a calculation must be passed on as a float to an API is not necessarily a good thing to do.

This is totally true, but it's important to realize that it takes a very long chain of multiplications or divisions (or a big positive or negative exponent) for any error to become significant in the end result. Especially in the scenario of a game. If we're speaking about AutoCAD calculations, this is another thing.

I'm sure there are exceptions, but in general, for 3D graphics, you don't need the precision of a double, and that's why 3D libraries mostly work on floats. The conversion for the API is indeed of little relevance, and I wasn't saying the opposite.

Don't get me wrong I'm not saying doubles shouldn't be used, if you need to write an hyperbolic sine function, then you want full 80-bit doubles since those are infinite chains and the user might need the full precision. But using them in a game to calculate 1.5kg * 9.81m/s2 is a little overkill as far as I'm concerned.

Of course, I doubt it's going to change anything to the player unless there's so many calculations that the extra work slows down the game. Likewise, the user probably won't notice it if you use 64-bit integers for a for loop...

Share this post


Link to post
Share on other sites
One important point is the 3D pipeline on most GPU's is optimised for floats. i.e. the hardware is organised to accept it.

so you notice in most modern 3d engines that values are stored as floats, even screen coordinates.

i.e. We used to have where we worked a font engine that used integer values for everything, positioning, size etc.

We found we had a huge increase in terms of optimisation turning them into float values because that is what the hardware expected.

So if a value is going to be passed along to the GPU consider floats.

Share this post


Link to post
Share on other sites

This topic is 2542 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this