Best (safest) way to convert from double to int

16,207

Solution 1

I think your best option would be to do:

checked
{
    try
    {
        int bar = (int)foo;
    }
    catch (OverflowException)
    {
     ...          
    }
}

From Explicit Numeric Conversions Table

When you convert from a double or float value to an integral type, the value is truncated. If the resulting integral value is outside the range of the destination value, the result depends on the overflow checking context. In a checked context, an OverflowException is thrown, while in an unchecked context, the result is an unspecified value of the destination type.

Note: Option 2 also throws an OverflowExceptionwhen required.

Solution 2

I prefer option 2.

One thing you need to do is check for exceptions though to confirm it worked, the same way you're checking 'parsed' in option 1:

try
{
    bar = Convert.ToInt32(foo); 
}
catch(OverflowException)
{
    // no can do!
{

If you were converting string etc instead of double, you might get a 'FormatException' instead.

Edit

I originally said option 2 wasn't particularly better than option 1, which @0xA3 pointed out was wrong. Option 1 is worse because it converts to a string before being parsed to an integer, which means it's less efficient. You also don't get an OverflowException if the double is outside the integer range (which you may or may not want) - although 'parsed' will be False in this case.

Solution 3

I realize this is not quite what the OP was asking for, but this info could be handy.

Here is a comparison (from http://www.dotnetspider.com/resources/1812-Difference-among-Int-Parse-Convert-ToInt.aspx)

        string s1 = "1234";
        string s2 = "1234.65";
        string s3 = null;
        string s4 = "12345678901234567890123456789012345678901234567890";

        int result;
        bool success;

        result = Int32.Parse(s1);      // 1234
        result = Int32.Parse(s2);      // FormatException
        result = Int32.Parse(s3);      // ArgumentNullException
        result = Int32.Parse(s4);      // OverflowException

        result = Convert.ToInt32(s1);      // 1234
        result = Convert.ToInt32(s2);      // FormatException
        result = Convert.ToInt32(s3);      // 0
        result = Convert.ToInt32(s4);      // OverflowException

        success = Int32.TryParse(s1, out result);      // 1234
        success = Int32.TryParse(s2, out result);      // 0
        success = Int32.TryParse(s3, out result);      // 0
        success = Int32.TryParse(s4, out result);      // 0

Solution 4

Option 3a not using exceptions, always returns a value:

    Int32 Convert(Double d)
    {
        if (d <= (double)Int32.MinValue)
            return Int32.MinValue;
        else if (d >= (double)Int32.MaxValue)
            return Int32.MaxValue;
        else 
            return (Int32)d;
    }

Solution 5

I would use option two. Short, clean and it works.

You could also look into the BigInteger class in .Net4, and you wouldn't have to check for overflow.

double foo = 1;            
BigInteger bigint = new BigInteger(foo);
Share:
16,207

Related videos on Youtube

Joel B
Author by

Joel B

Jesus Christ is LORD is really the only thing worth saying.

Updated on May 01, 2022

Comments

  • Joel B
    Joel B almost 2 years

    I'm curious as to the best way to convert a double to an int. Runtime safety is my primary concern here (it doesn't necessarily have to be the fastest method, but that would be my secondary concern). I've left a few options I can come up with below. Can anyone weigh in on which is best practice? Any better ways to accomplish this that I haven't listed?

            double foo = 1;
            int bar;
    
            // Option 1
            bool parsed = Int32.TryParse(foo.ToString(), out bar);
            if (parsed)
            {
                //...
            }
    
            // Option 2
            bar = Convert.ToInt32(foo);
    
            // Option 3
            if (foo < Int32.MaxValue && foo > Int32.MinValue) { bar = (Int32)foo; }
    
    • Dave Swersky
      Dave Swersky over 13 years
      What do you mean by "runtime safety"?
  • Admin
    Admin over 13 years
    Didn't know that. It checks NaN's too?
  • Ani
    Ani over 13 years
    @jdv: Yes, it does check NaNs and Infinities.
  • Dirk Vollmar
    Dirk Vollmar over 13 years
    Note that the OP asks about conversion from double to int, not string to int.
  • Dirk Vollmar
    Dirk Vollmar over 13 years
    Option 2 is clearly better than option 1. Option 1 comes with an additional conversion of the double to string which is unnecessary.
  • Grant Crofton
    Grant Crofton over 13 years
    Yeah, you're right, it is. I was initially thinking about converting from strings for some reason. Down with option 1!
  • Joel B
    Joel B over 13 years
    I like it...and for code clarity i think explicit casts just look more concise. Thanks @Ani!
  • Joel B
    Joel B over 13 years
    yeah, definitely handy. Thanks for the input!
  • Mikael Svenson
    Mikael Svenson over 13 years
    Another possibility which I added to my answer is the usage of BigInteger in .Net4.
  • Tohid
    Tohid about 4 years
    Nice answer, if you need to get an integer anyway.