C# - Convert decimal to int32

21,521

Solution 1

Convert is using rounding to nearest, or banker's rounding:

The behavior of this method follows IEEE Standard 754, section 4. This kind of rounding is sometimes called rounding to nearest, or banker's rounding. It minimizes rounding errors that result from consistently rounding a midpoint value in a single direction.

To control the type of rounding used by the Round method, call the Math.Round(Double, MidpointRounding) overload.

Solution 2

int a = (int)Math.Floor(4.5m);
int b = (int)Math.Floor(5.5m);

MSDN:

Or:

int a = decimal.ToInt32(4.5m);
int b = decimal.ToInt32(4.5m)

You can also just use the explicit int cast operator:

int a = (int) 4.5m;
int b = (int) 5.5m;

But read this note from MSDN:

This operator supports the explicit conversion of a Decimal to a Int32. The syntax for such explicit conversions is language-dependent, and individual language compilers can provide different implementations and return different results. The example illustrates the different return values when you explicitly convert a Decimal value to an Int32 value by using C# and Visual Basic. To perform a conversion that is independent of language, you can call the ToInt32 or the Convert.ToInt32(Decimal) method.


Math.Floor Method (Decimal)

Returns the largest integer less than or equal to the specified decimal number.

Note that decimal is bigger than int so if the value is bigger than int.MaxValue you get an OverflowException

Solution 3

Math.Round() allows you to choose

Console.WriteLine(Math.Round(4.5m, 0, MidpointRounding.ToEven));  //4
Console.WriteLine(Math.Round(5.5m, 0, MidpointRounding.ToEven));  //6

Console.WriteLine(Math.Round(4.5m, 0, MidpointRounding.AwayFromZero));  //5
Console.WriteLine(Math.Round(5.5m, 0, MidpointRounding.AwayFromZero));  //6

(And, as you would guess, default is ToEven)

Solution 4

It does that because that's how it's defined (see below for reason):

Returns: value, rounded to the nearest 32-bit signed integer. 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.

you'd have to use something like Math.Floor if you want different results.

The documentation for Math.Round, which does the same thing, states the reason:

The behavior of this method follows IEEE Standard 754, section 4. This kind of rounding is sometimes called rounding to nearest, or banker's rounding. It minimizes rounding errors that result from consistently rounding a midpoint value in a single direction.

To control the type of rounding used by the Round(Decimal) method, call the Math.Round(Decimal, MidpointRounding) overload.

Share:
21,521
šljaker
Author by

šljaker

do { coding; } while (!endOfLife);

Updated on July 05, 2022

Comments

  • šljaker
    šljaker almost 2 years

    I have the following code:

    int a = Convert.ToInt32(4.5m);
    int b = Convert.ToInt32(5.5m);
    
    Console.WriteLine(a);
    Console.WriteLine(b);
    

    And here's the output:

    4
    6
    

    Why does Convert.ToInt32 rounds decimal values to the nearest even number?