답변:
사용 Convert.ToInt32
에서 mscorlib
와 같이
decimal value = 3.14m;
int n = Convert.ToInt32(value);
MSDN을 참조하십시오 . 을 사용할 수도 있습니다 Decimal.ToInt32
. 다시 한 번 MSDN을 참조하십시오 . 마지막으로 다음과 같이 직접 캐스트를 수행 할 수 있습니다.
decimal value = 3.14m;
int n = (int) value;
명시 적 캐스트 연산자를 사용합니다. MSDN을 참조하십시오 .
null
대 0
대 ""
). 유연성이 절대적으로 필요한 경우가 아니라면 (예 : 동적 유형 시나리오) 변환을 사용하지 않는 것이 좋습니다.
OverflowException
입니다. 나는 @Will 여기에 더 나은 해답을 제공하고 있다고 생각 stackoverflow.com/a/501165/39532
Convert.ToInt32
하고 Decimal.ToInt32
다르게 행동 하십시오 . MSDN에서 : Decimal.ToInt32
-반환 값은 10 진수 값의 정수 부분입니다. 소수 자릿수가 잘립니다 . Convert.ToInt32
- 반환 값은 반올림 가장 가까운 32 비트 부호있는 정수. 값이 두 정수 사이의 중간이면 짝수가 리턴됩니다. 즉, 4.5는 4로 변환되고 5.5는 6으로 변환됩니다.
당신은 할 수 없습니다.
글쎄, 당신은 물론 수 ,하지만 int로 (선택 System.Int32) 가능한 모든 소수점 값을 보유 할 큰 충분하지 않습니다.
즉, int.MaxValue보다 큰 10 진수를 캐스팅하면 오버플로가 발생하고 10 진수가 int.MinValue보다 작 으면 언더 플로가 발생합니다.
언더 플로 / 오버플로는 어떻게됩니까? 두 가지 중 하나입니다. 빌드가 선택되지 않은 경우 (즉, CLR은 사용자가 관심을 가지지 않는 경우) 값 오버 / 언더 플로우 이후에도 애플리케이션이 계속되지만 int의 값은 예상 한 값이 아닙니다. 이로 인해 간헐적 인 버그가 발생할 수 있으며 수정하기가 어려울 수 있습니다. 응용 프로그램이 알 수없는 상태가되어 응용 프로그램에서 작동하는 중요한 데이터가 손상 될 수 있습니다. 안좋다.
어셈블리가 검사되면 (속성-> 빌드-> 고급-> 산술 오버플로 / 언더 플로우 또는 / 확인 된 컴파일러 옵션 확인) 언더 / 오버플로가 발생할 때 코드에서 예외가 발생합니다. 아마도 그렇지 않은 것보다 낫습니다. 그러나 어셈블리의 기본값은 오버플로 / 언더 플로를 확인하지 않는 것입니다.
실제 질문은 "무엇을하려고합니까?"입니다. 요구 사항을 알지 못하면 이 사례에서 해야 할 일을 분명하게 말할 수 있습니다 .
특별히 신경 쓰지 않으면 여기에 대한 답변이 유효합니다. 그러나, 당신은해야 통신 오버 플로우가 발생할 수 있음을 이해하고 그것은 당신의 캐스트 코드를 래핑하여 문제가되지 않음을 선택하지 않은 블록
unchecked
{
// do your conversions that may underflow/overflow here
}
그렇게하면 사람들이 당신이 걱정하지 않는다는 것을 이해하고, 나중에 누군가가 빌드를 / 확인으로 변경하면 코드가 예기치 않게 중단되지 않습니다.
경우 당신이 원하는 모든 정수 부분을 떠나, 숫자의 소수 부분을 삭제, 당신은 Math.Truncate를 사용할 수 있습니다.
decimal actual = 10.5M;
decimal expected = 10M;
Assert.AreEqual(expected, Math.Truncate(actual));
int i = (int)d;
반올림 한 숫자를 알려줍니다.
가장 가까운 짝수로 반올림하려는 경우 (예 :> .5는 올림)
int i = (int)Math.Round(d, MidpointRounding.ToEven);
일반적으로 C #의 모든 숫자 유형간에 캐스트 할 수 있습니다. 전송 중에 손실 될 정보가없는 경우 암시 적으로 수행 할 수 있습니다.
int i = 10;
decimal d = i;
원하는 경우 여전히 명시 적으로 수행 할 수 있습니다.
int i = 10;
decimal d = (decimal)i;
그러나 캐스트를 통해 정보를 잃어 버리려는 경우 명시 적으로해야합니다 (정보가 손실 될 수 있음을 알기 위해).
decimal d = 10.5M;
int i = (int)d;
여기서 당신은 ".5"를 잃고 있습니다. 괜찮을 수도 있지만 정보를 잃어 버렸음을 알 수 있도록 명시 적으로 캐스트해야합니다.
ToEven
통계적 표류를 막아야합니다. 그러나 유료 품목이나 돈으로 운영하는 경우 AwayFromZero
올바른 선택 인 것 같습니다.
decimal d = 2;
int i = (int) d;
이것은 잘 작동합니다.
decimal vIn = 0.0M;
int vOut = Convert.ToInt32(vIn);
다음은 다른 것들에 대한 매우 편리한 변환 데이터 유형 웹 페이지입니다. http://www.convertdatatypes.com/Convert-decimal-to-int-in-CSharp.html
빠른 반올림을위한 깔끔한 트릭은 10 진수를 정수로 변환하기 전에 0.5를 추가하는 것입니다.
decimal d = 10.1m;
d += .5m;
int i = (int)d;
여전히 나뭇잎 i=10
이지만
decimal d = 10.5m;
d += .5m;
int i = (int)d;
그렇게 반올림합니다 i=11
.
내가 사용하여 선호 Math.Round , Math.Floor , Math.Ceiling 또는 Math.Truncate을 적절하게 명시 적으로 설정 반올림 모드로.
Decimal은 Int32보다 넓은 범위의 값을 가지므로 여전히 캐스트하고 오버플로 / 언더 플로를 확인해야합니다.
checked {
int i = (int)Math.Floor(d);
}
박스형 십진수 (예 : 객체 유형 내부의 십진수 값)가 있으면 캐스팅 연산자가 작동하지 않는다는 것을 알았습니다. 이 경우 Convert.ToInt32 (decimal as object)가 제대로 작동합니다.
이 상황은 데이터베이스에서 IDENTITY / AUTONUMBER 값을 검색 할 때 발생합니다.
SqlCommand foo = new SqlCommand("INSERT INTO...; SELECT SCOPE_IDENTITY()", conn);
int ID = Convert.ToInt32(foo.ExecuteScalar()); // works
int ID = (int)foo.ExecuteScalar(); // throws InvalidCastException
SELECT SCOPE_IDENTITY()
은 .NET numeric(38, 0)
에 decimal
의해 번역 된 것을 반환합니다 . 로 캐스팅 할 수없는 boxed를 foo.ExecuteScalar()
반환 합니다 . 또는 작동합니다. decimal
object
int
(int)(decimal)foo.ExecuteScalar()
Convert.ToInt32(foo.ExecuteScalar())
int 범위를 벗어난 10 진수를 변환하려고 할 때 발생하는 OverflowException / UnderflowException을 처리하는 것으로 대답이 없습니다.
int intValue = (int)Math.Max(int.MinValue, Math.Min(int.MaxValue, decimalValue));
이 솔루션은 10 진수 값이 int 범위를 벗어나면 가능한 최대 또는 최소 int 값을 반환합니다. 값이 int 범위 내에있을 때 Math.Round, Math.Ceiling 또는 Math.Floor를 사용하여 반올림을 추가 할 수 있습니다.