long을 int로 변환 할 수 있습니까?


답변:


218

그냥하세요 (int)myLongValue. unchecked컨텍스트 (컴파일러 기본값) 에서 원하는 것을 정확하게 수행합니다 (MSB를 삭제하고 LSB를 가져 옵니다). 이 던질거야 OverflowExceptionchecked값이에 맞지 않을 경우 상황 int:

int myIntValue = unchecked((int)myLongValue);

15
같은 질문을 가진 다른 사람에게는 내가 한 일이 있습니다 .MSB를 삭제 하면 결과 의 부호 에 영향을 줄 수 있습니다. 위의 myIntValue경우 myLongValue양수 ( 4294967294 => -2)이고 그 반대의 경우 ( -4294967296 => 0) 음수로 끝날 수 있습니다 . CompareTo예를 들어, 작업을 구현할 때 long서로 빼는 결과를 행복하게 캐스팅하여 int반환 할 수 없습니다 . 일부 값의 경우 비교 결과가 올바르지 않습니다.
TJ Crowder

21
@Chris : 후드 아래에서 new Random()사용 Environment.TickCount합니다. 시계 틱으로 수동 시드 할 필요가 없습니다.
Mehrdad Afshari

@MehrdadAfshari는 항상 그랬습니까?
Chris Marisic

3
이것이 몇 년 전 이었지만, 새로운 랜덤에서 그것을 사용한 이유는 단위 테스트에서 동일한 정확한 결과를 얻었고 분산을 원했기 때문입니다. 숫자를 사용하면 차이가 생겼습니다.
Chris Marisic

3
기본 컨텍스트는 unchecked이므로 명시 적으로 변경하지 않으면 unchecked키워드 (이 답변 및 @ChrisMarisic의 의견 등)에 표시된 키워드가 필요하지 않으며 int myIntValue = (int)myLongValue정확히 동일합니다. 그러나 unchecked키워드 사용 여부에 관계없이 @TJCrowder가 설명하는 비 수학적 무례 자르기 동작이 발생하여 일부 오버플로 경우 부호가 뒤집힐 수 있습니다. 수학적 정확성을 실제로 보장하는 유일한 방법은 checked(...)상황 을 사용하는 것입니다. 이러한 경우에는 예외가 발생합니다.
Glenn Slayden

35
Convert.ToInt32(myValue);

int.MaxValue보다 클 때 어떻게 될지 모르겠습니다.


42
"나는 int.MaxValue보다는 그것의 더 큰이 때이 어떤 작업을 수행하는지 모른다 비록" 그것은이 발생합니다 OverflowException영업 이익이 원하지 않는 정확히 무엇 인 : msdn.microsoft.com/en-us/library/d4haekc4.aspx
TJ Crowder

4
myValue> Integer.Max 일 때 다른 처리를 수행해야하는 경우 변환을 실행하기 전에 myValue> Integer.Max인지 테스트하십시오. 그렇지 않으면 Convert.ToInt32 (myValue)가 오버플로됩니다 (예외는 없습니다). 이 방법은 VB.NET에서도 작동합니다.
TamusJRoyce

3
(int)는 유효하지만 Convert가 더 좋습니다. 이상한 데이터보다 이상한 예외를 갖는 것이 좋습니다.
Richard June

1
@RichardJune 음, 아니? 영업 이익은 여기에서 명시 적으로 말한다, " 긴의 값이> int.MaxValue, 내가 주위에 포장 할 수 기쁘게 생각합니다. "나는 일반적으로 명세서를 주장 볼 수 있지만에서 이 특정한 케이스 , 아니, Convert좋지 않다.
ruffin

if (value > Int32.MaxValue) return Int32.MaxValue; else return Convert.ToInt32( value );
Sergey

15

때로는 실제 값에 관심이 없지만 checksum / hashcode 로 사용하는 데 관심이 있습니다. 이 경우 내장 방법 GetHashCode()이 적합합니다.

int checkSumAsInt32 = checkSumAsIn64.GetHashCode();

7
해시 코드 구현이 .NET 버전마다 다를 수 있다고 언급하고 싶지만이 답변이 제공된 지 오래되었습니다. 실제로 발생하지 않을 수도 있지만이 값이 다른 응용 프로그램 실행 / 애플리케이션간에 동일하다는 보장은 없습니다.
Caramiriel

1
@Caramiriel의 말에 추가하려면 : 현재 해시 코드 로 임시 해시 코드 로 사용 GetHashCode하는 경우 적절한 선택입니다. 당신이 후에 경우 지속적으로 체크 - 나중에 응용 프로그램을 실행할 때 동일합니다 값, 다음 사용하지 않는 GetHashCode것이 영원히 동일한 알고리즘이 보장되지 않는.
ToolmakerSteve

9

안전하고 빠른 방법은 전송하기 전에 비트 마스킹을 사용하는 것입니다.

int MyInt = (int) ( MyLong & 0xFFFFFFFF )

0xFFFFFFFFInt 크기는 컴퓨터에 따라 다르므로 비트 마스크 ( ) 값은 Int 크기에 따라 다릅니다.


결과가 오버플로되거나 음수가 될 때 수행 할 작업을 결정해야합니다. 당신이 보여주는 것은 여전히 ​​넘칠 것입니다 .IIRC는 부호 비트를 통과시키기 때문에. [다른 답변에서 언급했듯이 unchecked컨텍스트에서는 오버플로가 발생하지 않지만 오버플로 unchecked를 피하기 위해 마스킹 할 필요는 없으므로 checked컨텍스트 에서만 솔루션이 필요합니다 .] 16 비트의 예. 부호있는 16 비트 보류 (-32768, 32767). 0xFFFF를 사용한 마스킹은 최대 65535의 값을 허용하여 오버플로 IIRC를 발생시킵니다. 양수 만 원하는 경우 부호 비트 0x7FFF 또는 0x7FFFFFFF를 피하기 위해 마스크 할 수 있습니다.
ToolmakerSteve

1

그것은에 의해 변환 할 수 있습니다

Convert.ToInt32 메서드

그러나 값이 Int32 유형의 범위를 벗어나면 OverflowException이 발생합니다. 기본 테스트는 작동 방식을 보여줍니다.

long[] numbers = { Int64.MinValue, -1, 0, 121, 340, Int64.MaxValue };
int result;
foreach (long number in numbers)
{
   try {
         result = Convert.ToInt32(number);
        Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.",
                    number.GetType().Name, number,
                    result.GetType().Name, result);
     }
     catch (OverflowException) {
      Console.WriteLine("The {0} value {1} is outside the range of the Int32 type.",
                    number.GetType().Name, number);
     }
}
// The example displays the following output:
//    The Int64 value -9223372036854775808 is outside the range of the Int32 type.
//    Converted the Int64 value -1 to the Int32 value -1.
//    Converted the Int64 value 0 to the Int32 value 0.
//    Converted the Int64 value 121 to the Int32 value 121.
//    Converted the Int64 value 340 to the Int32 value 340.
//    The Int64 value 9223372036854775807 is outside the range of the Int32 type.

여기에 더 이상 설명이있다.


0

하지 않을

(int) Math.Min(Int32.MaxValue, longValue)

수학적으로 말하면 올바른 방법일까요?


이 것 클램프longValue가장 가까운 표현할에 int원래 값이 큰에있는 경우. 그러나 너무 부정적인 입력에 대한 동일한 처리가 부족하여 대신 가장 중요한 비트가 손실됩니다. 당신 Int32.MinValue도 비교해야합니다 . 그러나 원래 포스터는 클램핑을 원하지 않는 것 같습니다.
Jeppe Stig Nielsen

IMHO는 때때로 잘못된 값보다 예외를 얻는 것이 낫습니다. Int32.MaxValue는 다음과 같습니다.
G. Goncharov

0

값이 정수 범위를 벗어난 경우 다음 솔루션은 int.MinValue / int.MaxValue로 잘립니다.

myLong < int.MinValue ? int.MinValue : (myLong > int.MaxValue ? int.MaxValue : (int)myLong)

0

가능한 방법은 모듈러스 연산자를 사용하여 값을 int32 범위에만 유지 한 다음 int로 캐스트하는 것입니다.

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