Casting float to int is interesting. Not only it causes the value to get truncated, but it also changes binary representation. When you want to cast float to int you have two options:

1) If you came from c/c++, there are several ways to do cast operations but the natural thing would be to use (int).

2) You can also use the Convert class to do the job (C#).

Check this code:

float f1 = 4.5F;
int i1 = (int)f1;
int j1 = Convert.ToInt32(f1);
float f2 = 5.5F;
int i2 = (int)f2;
int j2 = Convert.ToInt32(f2);

The result is: i1=4, j1=4, i2=5, j2=6

Let’s understand what’s going on here: The first result is obvious – truncating whatever is after the dot.

Open Reflector and look at the Convert code to understand the second result:

public static int ToInt32(double value)
{
    if (value >= 0.0)
    {
        if (value < 2147483647.5)
        {
            int num = (int) value;
            double num2 = value - num;
            if ((num2 > 0.5) || ((num2 == 0.5) && ((num & 1) != 0)))
            {
                num++;
            }
            return num;
        }
    }
    else if (value >= -2147483648.5)
    {
        int num3 = (int) value;
        double num4 = value - num3;
        if ((num4 < -0.5) || ((num4 == -0.5) && ((num3 & 1) != 0)))
        {
            num3--;
        }
        return num3;
    }
    throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
}

If value is halfway between two whole numbers, the even number is returned; that is, 4.5 is converted to 4, and 5.5 is converted to 6.

This is not a trivial result so you have to be careful here!

On the one hand, the first is quicker. on the other hand, the second is safer…

What to use? you decide…

Tags :

7 Responses to “Why Convert.ToInt32 Might be Dangerous”


  1. jrummell

    Said on March 26, 2008 :

    I believe this is because it uses the round to even method (http://en.wikipedia.org/wiki/Rounding#Round-to-even_method)

  2. shaharyr

    Said on March 26, 2008 :

    You are right jrummell, as written in the link that you provided this is called “bankers’ rounding”.
    I understand why banks need this behaviour (to be fair), what i can’t understand is why should we have this unexpected behaviour in the .Net framework.

  3. Nick Berardi

    Said on March 27, 2008 :

    What you are actually seeing is something called mid-point rounding. It is often used in accounting systems to round to the nearest even number. However the rounding that we were taught in school is to move away from zero.

    http://msdn2.microsoft.com/en-us/library/system.midpointrounding.aspx

    If you want what you are expecting as the outpu you need to do

    (int)Math.Round(f1, 0, MidpointRounding.AwayFromZero);

  4. Augustina Hulen

    Said on August 18, 2011 :

    A leopard cannot change its spots

3 Trackback(s)

  1. Mar 25, 2008: DotNetKicks.com
  2. Mar 26, 2008: Dew Drop - March 26, 2008 | Alvin Ashcraft's Morning Dew
  3. Apr 1, 2008: Finds of the Week - March 30, 2008 » Chinh Do

Post a Comment