프로그래밍 언어/C++

C / C ++에 표준 부호 함수 (signum, sgn)를 사용하는 방법

Rateye 2021. 8. 4. 10:41
728x90
반응형
질문 : C / C ++에 표준 부호 함수 (signum, sgn)가 있습니까?

음수에는 -1을, 양수에는 +1을 반환하는 함수를 원합니다. http://en.wikipedia.org/wiki/Sign_function 직접 작성하는 것은 쉽지만 어딘가에 표준 라이브러리에 있어야 할 것 같습니다.

편집 : 특히, 나는 수레에서 작동하는 기능을 찾고있었습니다.

답변

놀랍게도 아직 유형 안전 C ++ 버전을 게시 한 사람은 없습니다.

template <typename T> int sgn(T val) {
    return (T(0) < val) - (val < T(0));
}

혜택:

  • 실제로 signum (-1, 0 또는 1)을 구현합니다. 여기서 copysign을 사용하는 구현은 signum이 아닌 -1 또는 1 만 반환합니다. 또한 여기에서 일부 구현은 int가 아닌 float (또는 T)를 반환하므로 낭비적인 것 같습니다.
  • int, float, doubles, unsigned shorts 또는 정수 0에서 구성 할 수 있고 정렬 할 수있는 사용자 정의 유형에 대해 작동합니다.
  • 빠른! 특히 승격 한 다음 다시 좁혀 야하는 경우에는 copysign 이것은 분기가 없으며 훌륭하게 최적화됩니다.
  • 표준 준수! 비트 시프트 해킹은 깔끔하지만 일부 비트 표현에서만 작동하며 서명되지 않은 유형이 있으면 작동하지 않습니다. 적절한 경우 수동 전문화로 제공 될 수 있습니다.
  • 정확한! 0과의 간단한 비교는 기계의 내부 고정밀 표현 (예 : x87의 80 비트)을 유지하고 조기에 0으로 반올림하는 것을 방지 할 수 있습니다.

주의 사항 :

  • 템플릿이므로 어떤 상황에서는 컴파일하는 데 더 오래 걸릴 수 있습니다.
  • 분명히 어떤 사람들은 signum을 실제로 구현하지 않는 새롭고 다소 난해하며 매우 느린 표준 라이브러리 함수를 사용하는 것이 더 이해하기 쉽다고 생각합니다.
  • 검사의 < 0 부분은 서명되지 않은 유형에 대해 인스턴스화 될 때 -Wtype-limits 일부 오버로드를 사용하여이를 방지 할 수 있습니다.
    template <typename T> inline constexpr
    int signum(T x, std::false_type is_signed) {
        return T(0) < x;
    }
    
    template <typename T> inline constexpr
    int signum(T x, std::true_type is_signed) {
        return (T(0) < x) - (x < T(0));
    }
    
    template <typename T> inline constexpr
    int signum(T x) {
        return signum(x, std::is_signed<T>());
    }
    (첫 번째 경고의 좋은 예입니다.)

 

 

출처 : https://stackoverflow.com/questions/1903954/is-there-a-standard-sign-function-signum-sgn-in-c-c
728x90
반응형