Skip navigation

In this series I am going to share with you some programming gems – brief, novel techniques that I’ve picked up over the years that I believe every programmer should know.

Today’s gem: How to Round Up a Float

This isn’t a particularly ground breaking method – most veteran programmers probably know it – but for those of you who don’t, here’s the solution (at least, in most languages):

Add 0.5f to the value and cast it to an integer.  And optionally cast it back to a float, if you need a float.

Here’s the C# extension method that I include in my library project:

        public static float RoundUp(this float f)
            var v = f + 0.5f;
            if (v > int.MaxValue || v < int.MinValue)
                throw new ArgumentException("This value is too large or small to round with this method.  Use decimal formatting instead.", "f");
            return (float)((int)(v));

This works because if the original value’s decimal portion is less than 0.5f, which is the typical median value for rounding, then adding 0.5f to its value will not cause its singles digit to increase.  However, if the decimal portion is greater than 0.5f, the singles digit will increase.  Casting a float to an integer always truncates the decimal portion of the float regardless of its value, and by casting back to a float, you are given a decimal portion of (mostly) zeroes.  I say mostly because as we all know, floating point math is terrible.

The problem with the conversion method is that obviously the range of float is significantly larger than integer, so it doesn’t work for every situation.  Here are the versions I use for other primitives:

        public static decimal RoundUp(this decimal d)
            var dp = d + 0.5m;
            return Math.Truncate(dp);
        public static double RoundUp(this double d)
            var dp = d + 0.5d;
            return Math.Truncate(dp);

This would be the ideal method for floating point numbers as well, but there is no Math.Truncate method overload that takes a float.  I haven’t written one myself simply because I have never found a need to round a float that was larger than 2bn or less than negative 2bn.  If I had a number that large, I would probably just use a double and be done with it.

The reason that I keep the first (flawed) method around is because it’s incredibly easy to code, conserves memory by staying in the 4 byte world, and handles 99.9% of coding situations.  Seriously, how often do you have a float – a float mind you, not a decimal – for a number larger than 2 billion?

Use it, love it.

Speaking of floating point math being terrible, here’s another little gem that I always have in my toolbox:

How to evade the floating point precision dilemma in 1 easy method:

        public static bool Equals(this float f, float otherValue, float margin)
            return Math.Abs(f - otherValue) < margin;
// use it like:
var f = 1.0f;
var g = 1.01f;
var result = f.Equals(g, 0.1f); // value is true

There is probably a stock .NET method for doing this, but I don’t know what it is.  The .NET library is so large that even after working with it for as long as I have, I still find new classes and methods that I never knew about. 

Use this method in place of the == or object.Equals() methods when comparing floating point values.  If you’re going for true equality, set an acceptably low margin value, like 0.00001f.



Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: