C #에서 소수를 정수로 변환하는 방법은 무엇입니까?


227

십진수를 int로 어떻게 변환합니까?


11
가장 가까운 정수로 반올림했는지 또는 소수점 이하의 숫자 만 버리고 싶은지 아는 것이 도움이 될 것입니다
Dinah

128
나는 정직하게 질문을 내리는 데있어 요점을 알지 못한다. 예, Google에서 답을 찾을 수 있지만 사람들이 두 번째 질문을 모두 닫지 않으면 사이트의 품질이 향상되지 않습니까? 이 질문은 스팸이나 다른 것이 아니며, C #에 많은 새로운
이민자

답변:


268

사용 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을 참조하십시오 .


10
조심 : 변환 특정 변환을위한 몇 가지 놀라운 행동을 가지고 ( null0""). 유연성이 절대적으로 필요한 경우가 아니라면 (예 : 동적 유형 시나리오) 변환을 사용하지 않는 것이 좋습니다.
Eamon Nerbonne

1
-1은 decimal.MaxValue 및 decimal.MinValue와 같은 값에는 작동하지 않으므로 결과는 -1 OverflowException입니다. 나는 @Will 여기에 더 나은 해답을 제공하고 있다고 생각 stackoverflow.com/a/501165/39532
mezoid

8
조심 Convert.ToInt32하고 Decimal.ToInt32다르게 행동 하십시오 . MSDN에서 : Decimal.ToInt32-반환 값은 10 진수 값의 정수 부분입니다. 소수 자릿수가 잘립니다 . Convert.ToInt32- 반환 값은 반올림 가장 가까운 32 비트 부호있는 정수. 값이 두 정수 사이의 중간이면 짝수가 리턴됩니다. 즉, 4.5는 4로 변환되고 5.5는 6으로 변환됩니다.
vezucci

67

당신은 할 수 없습니다.

글쎄, 당신은 물론 ,하지만 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));

3
입력이 10 진수 인 경우 후드 아래에서 동일한 것으로 생각되지만 Math.Truncate보다 Decimal.Truncate를 사용하는 것이 더 편안합니다. 10 진법이 아닌 10 진법과는 달리 10 진법이 아닙니다.
Brian

7
확인되지 않은 컨텍스트는 소수점에 적용되지 않습니다. 소수에 대한 연산은 관계없이 OverflowException을 발생시킵니다.
Dave

46
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"를 잃고 있습니다. 괜찮을 수도 있지만 정보를 잃어 버렸음을 알 수 있도록 명시 적으로 캐스트해야합니다.


1
> *. 5가 항상 위의 샘플 출력을보고있는 위의 코드를 사용해 본 내 경험에 따라 항상 반올림하려면 MidpointRounding.AwayFromZero를 원합니다. msdn.microsoft.com/en-us/library/…
Elijah Lofgren

@ElijahLofgren 그것은 다음에 달려 있습니다 : 통계를하고 있다면 ToEven통계적 표류를 막아야합니다. 그러나 유료 품목이나 돈으로 운영하는 경우 AwayFromZero올바른 선택 인 것 같습니다.
mbx

22
decimal d = 2;
int i = (int) d;

이것은 잘 작동합니다.


명시적인 변환 정보를 사용하면 조심해야합니다.
Phaedrus

21
10 진수를 int로 변환하면 정보가 거의 항상 손실되지만 그 점이 중요하다고 생각합니다.
Dinah 2016


8

System.Decimal멤버 IConvertable가있는 인터페이스를 구현합니다 ToInt32().

전화 System.Decimal.ToInt32()는 당신을 위해 작동 합니까 ?


2
에서 문서 : "이 API는 .NET Framework 인프라를 지원하며 사용자 코드에서 직접 사용할 수 없습니다." 왜 Convert.ToInt32를 사용하지 않습니까?
H.Wolper

7

빠른 반올림을위한 깔끔한 트릭은 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.


5
Math.Floor와 Math.Ceiling이있을 때 왜 이렇게 귀찮게합니까?
Badaro

당시 나는 C #을 처음 접했고 어떤 이유로 든 이러한 기능이 존재한다는 것을 알지 못했습니다. 실제로 C / C ++에서 배운 트릭입니다. 분명히 더 유용했습니다.
DeadlyBrad42

1
소수점 값이 예를 들어 -9.3이면 어떻게 되나요?
supercat

6

내가 사용하여 선호 Math.Round , Math.Floor , Math.Ceiling 또는 Math.Truncate을 적절하게 명시 적으로 설정 반올림 모드로.

Decimal은 Int32보다 넓은 범위의 값을 가지므로 여전히 캐스트하고 오버플로 / 언더 플로를 확인해야합니다.

 checked {
   int i = (int)Math.Floor(d);
 }


6

소수를 가장 가까운 정수로 반올림

decimal a ;
int b = (int)(a + 0.5m);

a = 49.9, 다음b = 50

a = 49.5, 다음b = 50

언제 a = 49.4다음 b = 49


0

박스형 십진수 (예 : 객체 유형 내부의 십진수 값)가 있으면 캐스팅 연산자가 작동하지 않는다는 것을 알았습니다. 이 경우 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

4.3.2 Unboxing 변환 참조


2
참조 용으로 더 추가하면 동일한 원본 유형으로 만 상자를 개봉 할 수 있기 때문입니다. 다음 SELECT SCOPE_IDENTITY()은 .NET numeric(38, 0)decimal의해 번역 된 것을 반환합니다 . 로 캐스팅 할 수없는 boxed를 foo.ExecuteScalar()반환 합니다 . 또는 작동합니다. decimalobjectint(int)(decimal)foo.ExecuteScalar()Convert.ToInt32(foo.ExecuteScalar())
rageit

0

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를 사용하여 반올림을 추가 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.