šljaker
šljaker

Reputation: 7374

C# - Convert decimal to int32

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

Answers (6)

Botz3000
Botz3000

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

Dirk
Dirk

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

gdoron
gdoron

Reputation: 150313

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

Upvotes: 13

General Grey
General Grey

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

JonC
JonC

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

ie.
ie.

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

Related Questions