How do I convert a decimal to an int in C#?

Solution 1:

Use Convert.ToInt32 from mscorlib as in

decimal value = 3.14m;
int n = Convert.ToInt32(value);

See MSDN. You can also use Decimal.ToInt32. Again, see MSDN. Finally, you can do a direct cast as in

decimal value = 3.14m;
int n = (int) value;

which uses the explicit cast operator. See MSDN.

Solution 2:

You can't.

Well, of course you could, however an int (System.Int32) is not big enough to hold every possible decimal value.

That means if you cast a decimal that's larger than int.MaxValue you will overflow, and if the decimal is smaller than int.MinValue, it will underflow.

What happens when you under/overflow? One of two things. If your build is unchecked (i.e., the CLR doesn't care if you do), your application will continue after the value over/underflows, but the value in the int will not be what you expected. This can lead to intermittent bugs and may be hard to fix. You'll end up your application in an unknown state which may result in your application corrupting whatever important data its working on. Not good.

If your assembly is checked (properties->build->advanced->check for arithmetic overflow/underflow or the /checked compiler option), your code will throw an exception when an under/overflow occurs. This is probably better than not; however the default for assemblies is not to check for over/underflow.

The real question is "what are you trying to do?" Without knowing your requirements, nobody can tell you what you should do in this case, other than the obvious: DON'T DO IT.

If you specifically do NOT care, the answers here are valid. However, you should communicate your understanding that an overflow may occur and that it doesn't matter by wrapping your cast code in an unchecked block

unchecked
{
  // do your conversions that may underflow/overflow here
}

That way people coming behind you understand you don't care, and if in the future someone changes your builds to /checked, your code won't break unexpectedly.

If all you want to do is drop the fractional portion of the number, leaving the integral part, you can use Math.Truncate.

decimal actual = 10.5M;
decimal expected = 10M;
Assert.AreEqual(expected, Math.Truncate(actual));

Solution 3:

int i = (int)d;

will give you the number rounded down.

If you want to round to the nearest even number (i.e. >.5 will round up) you can use

int i = (int)Math.Round(d, MidpointRounding.ToEven);

In general you can cast between all the numerical types in C#. If there is no information that will be lost during the cast you can do it implicitly:

int i = 10;
decimal d = i;

though you can still do it explicitly if you wish:

int i = 10;
decimal d = (decimal)i;

However, if you are going to be losing information through the cast you must do it explicitly (to show you are aware you may be losing information):

decimal d = 10.5M;
int i = (int)d;

Here you are losing the ".5". This may be fine, but you must be explicit about it and make an explicit cast to show you know you may be losing the information.