HOWTO · Csharp
C#에서 decimal을 int로 변환
C#에서 decimal을 int로 변환할 때 절단, 반올림, 방향 지정 반올림을 선택하고 Int32 범위를 벗어난 값을 처리하는 방법을 설명합니다.
이 페이지의 내용
C#에서 decimal을 int로 변환할 때 소수 부분을 버리려면 명시적 캐스트를 사용하고, 가장 가까운 정수로 반올림하려면 Convert.ToInt32를 사용합니다. 항상 내림, 올림 또는 특정 중간값 규칙이 필요하다면 먼저 해당 규칙으로 반올림한 다음 캐스트합니다. 값이 Int32 범위를 벗어나면 모든 변환에서 OverflowException이 발생할 수 있습니다.
이는 표시 형식이 아니라 업무 규칙의 문제입니다. 예를 들어 -12.9m은 0을 향해 절단하면 -12가 되지만 Math.Floor로 내림하면 -13이 됩니다. 금액이나 측정값처럼 소수 부분이 중요하다면 값을 decimal로 유지하세요.
decimal을 0을 향해 절단하기
명시적 캐스트인 (int)value는 절단하려는 의도를 가장 분명하게 보여 줍니다. decimal 리터럴에는 m 접미사가 필요하며, 접미사가 없는 12.9는 double입니다. decimal을 정수형으로 변환하면 0을 향해 반올림되므로, 양수 소수에서는 결과가 더 작아지고 음수 소수에서는 결과가 더 커집니다. floor나 ceiling 규칙을 쓰는 것이 아닙니다. C# numeric conversions 문서에는 0을 향한 동작과 범위 초과 실패가 모두 설명되어 있습니다.
using System;
decimal positive = 12.9m;
decimal negative = -12.9m;
Console.WriteLine($"cast: {(int)positive}, {(int)negative}");
Console.WriteLine($"round: {Convert.ToInt32(12.5m)}, {Convert.ToInt32(13.5m)}");
try
{
decimal tooLarge = decimal.MaxValue;
Console.WriteLine(checked((int)tooLarge));
}
catch (OverflowException)
{
Console.WriteLine("overflow");
}
cast: 12, -12
round: 12, 14
overflow
첫 번째 출력은 절단 규칙을 보여 줍니다. 두 값 모두 소수 부분이 버려지고, 음수 값은 0을 향해 이동합니다. 마지막 출력은 경계 사례입니다. 이 예제에서는 checked로 오버플로 동작을 명시하고, 변환을 잡아서 프로그램이 종료되는 대신 조건을 보고합니다.
가장 가까운 정수로 반올림하기
Convert.ToInt32(decimal)는 절단 변환이 아닙니다. 가장 가까운 32비트 부호 있는 정수로 반올림하며, 소수 부분이 정확히 .5이면 짝수 쪽으로 반올림합니다. 검증된 예에서 12는 짝수이므로 12.5m은 12가 되고, 13.5m은 14가 됩니다. 값이 가장 가까운 전체 단위로 반올림되어야 하는 측정값에는 이 방식이 알맞을 수 있지만, 모든 중간값이 0에서 멀어질 것이라고 기대하면 의외의 결과가 됩니다.
애플리케이션에 필요한 정책이 짝수 반올림인지 확인한 후에만 Convert.ToInt32를 선택하세요. decimal 오버로드 문서에도 int 범위를 벗어난 값에서는 OverflowException이 발생한다고 명시되어 있습니다. 이 메서드는 너무 큰 decimal 값을 안전하게 만드는 방법이 아닙니다.
명시적인 반올림 규칙 선택하기
방향 지정 반올림에서는 먼저 decimal에 Math 메서드를 적용한 다음, 이미 정수가 된 결과를 변환합니다. Math.Floor는 음의 무한대를 향하고 Math.Ceiling은 양의 무한대를 향합니다. 따라서 이 규칙은 음수 소수에서 절단과 다르며, Math.Floor(-12.9m)는 -13m이고 (int)-12.9m는 -12입니다.
기본값과 다른 중간값 규칙이 필요하다면 코드를 통해 명시하세요. Math.Round(value, MidpointRounding.AwayFromZero)는 2.5m을 3m으로, -2.5m을 -3m으로 만듭니다. 반면 기본 Math.Round(decimal)는 짝수 반올림을 사용합니다. Math.Truncate도 0을 향해 정수화된 decimal을 얻는 명확한 선택지입니다.
먼저 캐스트하면 안 됩니다. (int)value에서 이미 소수 부분이 사라지므로 이후에 Math.Round를 호출해도 원래 의도한 규칙을 복구할 수 없습니다. 먼저 반올림하고 결과가 범위 안에 있는지 확인한 뒤 캐스트하세요.
int 범위를 벗어난 값 처리하기
int는 int.MinValue부터 int.MaxValue까지를 나타내는 32비트 부호 있는 정수입니다. decimal은 이 범위를 훨씬 넘어서는 값을 표현할 수 있습니다. 범위를 벗어난 값을 직접 변환하면 OverflowException이 발생하며 가장 가까운 끝점으로 자동 제한되지 않습니다.
범위를 벗어난 입력이 예상된다면 변환 전에 검증하거나, 값이 애플리케이션에 들어오는 경계에서 OverflowException을 처리하세요. API에 맞추기 위해 금액을 조용히 캐스트하지 마세요. 수신 계약에서 허용한다면 더 넓은 정수형을 선택하거나 decimal을 유지하세요. 좁은 형식이 의도된 것이고 테스트 중 오버플로를 반드시 드러내야 한다면 checked 변환이 유용합니다.
규칙에 맞는 변환 선택하기
| 원하는 결과 | 사용 방법 | 중요한 동작 |
|---|---|---|
| 소수 부분 버리기 | (int)value |
0을 향해 절단합니다. |
가장 가까운 int |
Convert.ToInt32(value) |
중간값은 짝수로 반올림합니다. |
| 항상 내림 또는 올림 | Math.Floor 또는 Math.Ceiling 후 캐스트 |
음수에서는 절단과 결과가 다릅니다. |
| 사용자 지정 중간값 규칙 | MidpointRounding와 함께 Math.Round 후 캐스트 |
동률 처리 규칙을 명시해야 합니다. |
일반적인 절단에는 명시적 캐스트가 권장되는 간결한 답입니다. 적용하려는 규칙이 그 반올림 정책일 때만 Convert.ToInt32나 Math 메서드를 선택하고, int 경계에서는 항상 OverflowException을 고려하세요.