문제

예방하는 가장 효과적인 방법은 무엇입니까? 산술 오버플로 그리고 언더플로?

마음속에 떠오르는 몇 가지 예는 다음과 같습니다.

  • 유효한 입력 범위를 기반으로 한 테스트
  • 형식적 방법을 사용한 검증
  • 불변의 사용
  • 언어 기능이나 라이브러리를 사용하여 런타임 시 감지(이로 인해 방지되지는 않음)
도움이 되었습니까?

해결책

한 가지 가능성은 오버플로/언더플로가 발생하지 않는 임의 크기의 정수가 있는 언어를 사용하는 것입니다.

그렇지 않은 경우, 이것이 정말로 우려되는 사항이고 언어에서 허용하는 경우 정수처럼 작동하지만 모든 작업에서 오버플로가 있는지 확인하는 래퍼 클래스를 작성하세요.디버그 빌드에 대한 검사를 수행하고 릴리스 빌드에 최적화된 상태로 둘 수도 있습니다.C++와 같은 언어에서는 이를 수행할 수 있으며 릴리스 빌드의 경우 정수와 거의 동일하게 작동하지만 디버그 빌드의 경우 전체 런타임 검사를 받게 됩니다.

class CheckedInt
{
private: 
    int Value;

public:
    // Constructor
    CheckedInt(int src) : Value(src) {}

    // Conversions back to int
    operator int&() { return Value; }
    operator const int &() const { return Value; }

    // Operators
    CheckedInt operator+(CheckedInt rhs) const
    {
        if (rhs.Value < 0 && rhs.Value + Value > Value)
            throw OverflowException();
        if (rhs.Value > 0 && rhs.Value + Value < Value)
            throw OverflowException();
        return CheckedInt(rhs.Value + Value);
    }

    // Lots more operators...
};

편집하다:

알고 보니 누군가가 C++에서는 이미 이 작업을 수행하고 있습니다. - 현재 구현은 Visual Studio에 중점을 두고 있지만 gcc도 지원되는 것 같습니다.

다른 팁

나는 내 코드의 범위/유효성 검사를 수행하기 위해 많은 테스트 코드를 작성합니다.이는 이러한 유형의 상황을 대부분 포착하는 경향이 있으며 더 많은 방탄 코드를 작성하는 데 확실히 도움이 됩니다.

다음과 같이 고정밀 부동 소수점 숫자를 사용하십시오. 긴 더블.

내 생각에는 목록에 매우 중요한 옵션 하나가 누락된 것 같습니다.작업에 적합한 프로그래밍 언어를 선택하십시오.고정된 크기의 정수가 없기 때문에 이러한 문제가 없는 프로그래밍 언어가 많이 있습니다.

어떤 언어를 사용할지 선택할 때 정수의 크기보다 더 중요한 고려 사항이 있습니다.값이 범위 내에 있는지 모르면 입력을 확인하고, 매우 드문 경우에는 예외 처리를 사용하세요.

불일치를 확인하는 래퍼는 많은 경우 의미가 있습니다.두 개 이상의 정수에 대한 덧셈 연산(예: 덧셈 또는 곱셈)의 결과가 피연산자보다 작은 값으로 나타나면 문제가 발생한 것입니다.모든 추가 작업은 다음과 같이 수행되어야 합니다.

if (sum < operand1 || sum < operand2)
    omg_error();

마찬가지로 논리적으로 더 작은 값을 생성해야 하는 모든 작업은 실수로 포함되었는지 확인해야 합니다.

코드에 오버플로가 없음을 증명하기 위해 형식적인 방법을 사용하여 코드를 검사해 보셨나요?추상 해석으로 알려진 형식적 방법 기술은 소프트웨어의 견고성을 검사하여 소프트웨어가 오버플로, 언더플로, 0으로 나누기, 오버플로 또는 기타 유사한 런타임 오류를 겪지 않는다는 것을 증명할 수 있습니다.이는 소프트웨어를 철저하게 분석하는 수학적 기법입니다.이 기술은 1970년대 패트릭 쿠소(Patrick Cousot)에 의해 개척되었습니다.이는 Arian 5 로켓의 오버플로로 인해 발사체가 파괴된 오버플로 상태를 진단하는 데 성공적으로 사용되었습니다.부동 소수점 숫자를 정수로 변환하는 동안 오버플로가 발생했습니다.이 기술에 대한 자세한 정보를 찾을 수 있습니다. 여기 그리고 또한 위키피디아.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top