2010-01-13 6 views
49

Project Euler (문제가되는 사이트)에서 문제 번호 10의 이상한 경험을했습니다. 할당은 2 백만 미만의 모든 소수의 합을 계산하는 것이 었습니다.C#에서 int에 대한 오버플로 예외가 없습니까?

나는 합계에 int를 사용했고, 내 알고리즘은 답을 냈지만 답을 확인하기 위해 붙여 넣었을 때 틀렸어.

결과가 너무 커서 int에 맞지는 않지만 오버플로 오류가 발생하지 않았습니까? 대신 방금 실제 응답에서 멀리 떨어진 값을 반환했습니다.

유형을 길게 변경하면 모든 것이 늠름한 것이 었습니다.

+5

당신은 정말 모든 정수 작업이 오버 플로우를 확인 하시겠습니까 것입니까? –

+4

글쎄,이 특별한 경우에 shure가 나에게 시간을 절약 해 주었다;) – erikric

+1

이 경우 yes입니다. 대다수의 작업은 오버플로가 될 수 없습니다. 컴파일러가이를 증명하고 결과로 검사를 사용하지 못하게하는 것이 흥미로울 것입니다. 그러나 나는 그것이 매우 의심 스럽습니다. – Thorarin

답변

73

정수 연산은 기본적으로 오버플로시 예외를 throw하지 않습니다. 당신은 프로젝트 설정을 통해, 또는 계산을 checked하여 그것을 얻을 수 있습니다

int result = checked(largeInt + otherLargeInt); 

이제 작업이 발생합니다.

반대의 경우는 unchecked이며 모든 작업이 명시 적으로 선택 취소됩니다. 분명히 이것은 프로젝트 설정에서 검사 된 작업을 사용할 때만 의미가 있습니다.

+0

디버그 모드에 있지 않는 한, int 연산은 기본적으로 체크됩니다. – Ant

+5

Nope. 이 문제가 발생했을 때 디버그 모드로 실행되었습니다. – erikric

+0

오. 나는 교정했다. Project Euler 프로젝트가 디버그 모드에서 오버플로에 대해 알려 주었다고 확신했습니다.:/ – Ant

19

C#에서 OverflowException이 발생하지 않습니다 (VB에서는 예외가 기본값으로 throw됩니다).

당신이 checked 맥락에서 코드를 삽입해야하는 excpetion으로 활용하려면 다음, 산술 들어

캐스팅, 또는 변환 작업이 던져 :

byte value = 241; 
checked 
{ 
    try 
    { 
     sbyte newValue = (sbyte) value; 
     Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", 
      value.GetType().Name, value, 
      newValue.GetType().Name, newValue); 
    } 
    catch (OverflowException) 
    { 
     Console.WriteLine("Exception: {0} > {1}.", value, SByte.MaxValue); 
    } 
}  

MSDN 더 자세히 설명을 OverflowException이 발생하면 작업이 확인 된 컨텍스트에서 발생해야합니다. 기본적으로 Visual Basic에서는 산술 연산과 오버플로가 검사됩니다. C#의 은 그렇지 않습니다. 검사되지 않은 컨텍스트에서 작업이 발생하면 대상 유형에 맞지 않는 상위 비트를 삭제하여 결과를 잘라냅니다.

6

내가 이미 CMT 추가했습니다,하지만 당신의 일부 아마도 흥미 :

msdn이 우리에게 알려줍니다 :

정수 산술 오버 플로우 중 하나 는 OverflowException 또는 폐기 대부분을 던졌습니다

유의 비트 결과 :

그러나

소수 산술 오버플로 항상 은 OverflowException을 발생시킵니다.

정수 오버 플로우가 발생

, 무슨 이 발생하는 것은 확인 또는 선택 해제 할 수있는 실행 상황에 따라 달라집니다. 확인 된 컨텍스트에서 OverflowException이 throw됩니다. 확인되지 않은 컨텍스트에서는 의 결과 비트가 이고 계속 실행됩니다. 따라서 C#에서는 을 처리하거나 오버플로를 무시하도록 선택할 수 있습니다.

+0

소수점은 주로 통화 또는 과학 계산에 사용되므로 오히려 던져 버리면 자동으로 실패합니다. – Snellface

6

기본적으로 C#에서는 정수에서 산술 오버플로가 있는지 확인하지 않습니다. /checkedcompiler option으로 변경하거나 Visual Studio (프로젝트 속성 - 빌드 - 고급)에서 "산술 오버플로/언더 플로우 검사"를 사용하도록 설정할 수 있습니다.

checked and unchecked keywords을 사용하면 사례별로 기본값을 무시할 수 있습니다. 코드 조각에서 수행되는 검사에 의존하는 경우 checked을 사용하여 명시 적으로 활성화하는 것이 좋습니다. 부동 소수점 연산이 OverflowException을 던져 결코 진수 작업은 항상 OverflowException을 던져

int j = checked(i * 2); 

checked 
{ 
    int j = i * 2; 
    // Do more stuff 
} 

참고. C# operators도 참조하십시오.

9

기본적으로 C#은 정수 오버플로 및 언더 플로에 대한 예외를 throw하지 않기 때문입니다. 여기서 할 수있는 일이 몇 가지 있습니다.

옵션 1

당신은 프로젝트로 이동에 의해 throw되는 예외를 활성화해야 => 속성 => 빌드 탭 => 고급 => 산술 오버 플로우 언더 플로우를 확인합니다. (반드시 당신을 체크 옵션)

enter image description here

당신이 옵션

012을 체크해야합니다

옵션 2

확인 된 블록을 사용하고 오버플로 예외를 발생시켜 상황을 처리하십시오. 샘플 코드는이 당신을 도울 것입니다

 try 
     { 
      checked 
      { 
       int y = 1000000000; 
       short x = (short)y; 
      } 
     } 
     catch (OverflowException ex) 
     { 
      MessageBox.Show("Overflow"); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Error"); 
     } 

희망 ... :)

+2

옵션 1은 많은 사람들이 모르는 요점입니다. 당신은 내 +1을 얻는다. – RBT

관련 문제