Reputation: 7374
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?
Upvotes: 12
Views: 24126
Reputation: 39660
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.
Upvotes: 4
Reputation: 2388
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
)
Upvotes: 5
Reputation: 150313
int a = (int)Math.Floor(4.5m);
int b = (int)Math.Floor(5.5m);
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
Upvotes: 13
Reputation: 3698
I read something yesterday that when rounding occurs it rounds to the nearest even number, its called bankers rounding. You have to tell it how you want to round
EDIT: you asked for an explanation of why it rounds to the nearest even number.
say you have 10 numbers (this is an extreme case
1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5
the sum = 60
if you round them all off first
the sum = 65 because they would all round up
if you bankers round them
the sum = 60
Upvotes: 0
Reputation: 978
From http://msdn.microsoft.com/en-us/library/93kx4xke
Return Value
Type: System.Int32 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.
Upvotes: 0
Reputation: 6101
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.
Upvotes: 13