Java는 int 또는 long 기본 유형의 정수 오버플로로 아무것도하지 않으며 양수 및 음수로 오버플로를 무시합니다.
이 답변은 먼저 정수 오버플로에 대해 설명하고 식 평가의 중간 값으로도 어떻게 발생할 수 있는지에 대한 예를 제공 한 다음 정수 오버플로를 방지하고 감지하기위한 자세한 기술을 제공하는 리소스에 대한 링크를 제공합니다.
예기치 않은 또는 감지되지 않은 오버플로에서 발생하는 정수 산술 및 식은 일반적인 프로그래밍 오류입니다. 예기치 않거나 감지되지 않은 정수 오버플로는 특히 배열, 스택 및 목록 객체에 영향을 미치므로 잘 알려진 악용 가능한 보안 문제입니다.
양수 또는 음수 값이 해당 기본 유형의 최대 값 또는 최소값을 초과하는 양수 또는 음수 방향으로 오버플로가 발생할 수 있습니다. 오버플로는 식 또는 연산 평가 중 중간 값에서 발생할 수 있으며 최종 값이 범위 내에있을 것으로 예상되는 식 또는 연산의 결과에 영향을줍니다.
때때로 부정적인 오버플로는 언더 플로라고 잘못 부릅니다. 언더 플로는 표현이 허용하는 것보다 값이 0에 가까울 때 발생합니다. 언더 플로는 정수 산술로 발생하며 예상됩니다. 정수 언더 플로우는 정수 평가가 -1과 0 또는 0과 1 사이 일 때 발생합니다. 소수 결과는 0으로 잘립니다. 이는 정수 산술에서는 정상이며 오류로 간주되지 않습니다. 그러나 코드가 예외를 발생시킬 수 있습니다. 정수 언더 플로의 결과가 식의 제수로 사용되는 경우 "ArithmeticException : / by zero"예외가 그 예입니다.
다음 코드를 고려하십시오.
int bigValue = Integer.MAX_VALUE;
int x = bigValue * 2 / 5;
int y = bigValue / x;
x에 0이 할당되고 bigValue / x에 대한 후속 평가에서 y에 값 2가 할당되는 대신 "ArithmeticException : / by zero"(예 : 0으로 나눔) 예외가 발생합니다.
x에 대한 예상 결과는 858,993,458이며 최대 int 값 2,147,483,647보다 작습니다. 그러나 Integer.MAX_Value * 2 평가의 중간 결과는 최대 int 값을 초과하고 2의 보수 정수 표현에 따라 -2 인 4,294,967,294입니다. -2/5의 후속 평가는 0으로 평가되어 x에 할당됩니다.
x를 계산하기위한 표현식을 평가할 때 다음 코드를 곱하기 전에 나누는 표현식으로 재 배열합니다.
int bigValue = Integer.MAX_VALUE;
int x = bigValue / 5 * 2;
int y = bigValue / x;
x에 858,993,458이 할당되고 y에 2가 할당되어 예상됩니다.
bigValue / 5의 중간 결과는 429,496,729이며 int의 최대 값을 초과하지 않습니다. 429,496,729 * 2의 후속 평가는 int의 최대 값을 초과하지 않으며 예상 결과는 x에 할당됩니다. y에 대한 평가는 0으로 나누지 않습니다. x와 y에 대한 평가는 예상대로 작동합니다.
Java 정수 값은 2의 보수 부호있는 정수 표현에 따라 저장되고 동작합니다. 결과 값이 최대 또는 최소 정수 값보다 크거나 작을 경우 2의 보수 정수 값이 대신 발생합니다. 가장 일반적인 정수 산술 상황 인 2s 보수 동작을 사용하도록 명시 적으로 설계되지 않은 상황에서는 결과 2s 보수 값으로 인해 위의 예와 같이 프로그래밍 논리 또는 계산 오류가 발생합니다. 훌륭한 Wikipedia 기사에서 2의 칭찬 이진 정수에 대해 설명합니다 : 2의 보수-Wikipedia
의도하지 않은 정수 오버플로를 피하는 기술이 있습니다. Techinque는 사전 조건 테스트, 업 캐스팅 및 BigInteger를 사용하여 분류 될 수 있습니다.
사전 조건 테스트는 산술 연산 또는 표현식으로 들어가는 값을 검사하여 해당 값으로 오버플로가 발생하지 않는지 확인합니다. 프로그래밍과 디자인은 입력 값이 오버플로를 유발하지 않도록 테스트를 생성 한 다음 입력 값이 발생하면 오버플로를 유발할 조치를 결정해야합니다.
업 캐스팅은 더 큰 기본 유형을 사용하여 산술 연산 또는 표현식을 수행 한 다음 결과 값이 정수의 최대 값 또는 최소값을 초과하는지 여부를 판별합니다. 업 캐스팅을 수행하더라도 조작 또는 표현식의 값 또는 일부 중간 값이 업 캐스트 유형의 최대 값 또는 최소값을 초과하여 오버 플로우가 발생하여 오버 플로우가 발생할 수 있으며, 이는 감지되지 않으며 예기치 않은 원하지 않는 결과를 초래할 수 있습니다. 업 캐스팅없이 예방할 수 없거나 실용적이지 않은 경우 분석 또는 사전 조건을 통해 업 캐스팅으로 오버플로를 방지 할 수 있습니다. 해당 정수가 이미 긴 기본 유형 인 경우 Java의 기본 유형으로 업 캐스팅 할 수 없습니다.
BigInteger 기술은 BigInteger를 사용하는 라이브러리 메소드를 사용하여 산술 연산 또는 표현식에 BigInteger를 사용하는 것으로 구성됩니다. BigInteger가 오버 플로우되지 않습니다. 필요한 경우 사용 가능한 모든 메모리를 사용합니다. 산술 방법은 일반적으로 정수 연산보다 약간 덜 효율적입니다. BigInteger를 사용한 결과가 정수의 최대 값 또는 최소값을 초과 할 수 있지만 결과로 이어지는 산술에서는 오버 플로우가 발생하지 않습니다. 프로그래밍 및 디자인은 BigInteger 결과가 원하는 기본 결과 유형 (예 : int 또는 long)의 최대 값 또는 최소값을 초과하는 경우 수행 할 조치를 결정해야합니다.
Carnegie Mellon Software Engineering Institute의 CERT 프로그램과 Oracle은 안전한 Java 프로그래밍을위한 일련의 표준을 만들었습니다. 정수 오버플로를 방지하고 감지하는 기술이 표준에 포함되어 있습니다. 이 표준은 자유롭게 액세스 할 수있는 온라인 리소스로 게시됩니다. Java 용 CERT Oracle Secure Coding Standard
정수 오버플로 방지 또는 감지를위한 코딩 기술의 실제 예를 설명하고 포함하는 표준 섹션은 다음과 같습니다. NUM00-J. 정수 오버플로 감지 또는 방지
CERT Oracle Secure Coding Standard for Java의 서적 및 PDF 양식도 제공됩니다.