C / C ++에 표준 부호 기능 (signum, sgn)이 있습니까?


409

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

편집 : 구체적으로, 나는 수레에서 작동하는 함수를 찾고있었습니다.


13
0으로 무엇을 반환해야합니까?
Craig McQueen

61
@Craig McQueen; 양의 0인지 음의 0인지에 따라 다릅니다.
ysth

1
반환 값을 정수로 지정했습니다. 정수 또는 부동 소수점 숫자를 취하는 솔루션을 찾고 있습니까?
Mark Byers

6
@ysth @Craig McQueen, 수레에 대해서도 거짓, 아니오? sgn (x)의 정의 는 if 경우 0을 반환한다고 말합니다 x==0. IEEE 754 에 따르면 , 음의 0과 양의 0은 동일한 것으로 비교해야합니다.
RJFalconer 2018 년

5
@ysth "양의 0 또는 음의 0에 의존합니다." 실제로는 그렇지 않습니다.
RJFalconer

답변:


506

아무도 타입 안전 C ++ 버전을 아직 게시하지 않았습니다.

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

혜택:

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

주의 사항 :

  • 템플릿이므로 일부 환경에서 컴파일하는 데 시간이 더 걸릴 수 있습니다.
  • 분명히 어떤 사람들은 실제로 signum을 구현하지 않는 새롭고 다소 난해하고 매우 느린 표준 라이브러리 함수를 사용 하는 것이 더 이해할 만하다고 생각합니다 .
  • < 0검사 의 일부 -Wtype-limits는 서명되지 않은 유형으로 인스턴스화 될 때 GCC의 경고를 트리거 합니다. 몇 가지 과부하를 사용하여이를 피할 수 있습니다.

    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>());
    }

    (첫 번째 경고의 좋은 예는 무엇입니까?)


18
@GMan : GCC (현재) (4.5)는 템플릿 함수의 인스턴스화 수에 이차적 인 비용이 들지 않았으며, 수동으로 작성된 함수 나 표준 C 전 처리기보다 구문 분석 및 인스턴스화하는 데 여전히 훨씬 더 비쌉니다. 또한 링커는 중복 인스턴스를 제거하기 위해 더 많은 작업을 수행해야합니다. 또한 템플릿은 # includes-in- # includes를 권장하므로 더 많은 파일을 다시 컴파일하기 위해 종속성 계산에 더 길고 작은 (종종 인터페이스가 아닌 구현) 변경이 필요합니다.

15
@ 조 : 예, 여전히 눈에 띄는 비용은 없습니다. C ++은 템플릿을 사용하는데, 이는 우리 모두가 이해하고 받아들이고 극복해야하는 것입니다.
GManNickG

42
잠깐,이 "copysign is slow"사업은 무엇입니까? 현재 컴파일러 (g ++ 4.6 +, clang ++ 3.0) std::copysign를 사용하면 4 개의 명령 (인라인 된), 분기 없음, 전적으로 FPU를 사용하는 훌륭한 코드가 될 것 같습니다. 대조적으로,이 답변에서 주어진 레시피는 훨씬 더 나쁜 코드를 생성합니다 (정수 단위와 FPU 사이에서 앞뒤로 이동하는 것을 포함하여 더 많은 명령어).
snogglethorpe

14
@ snogglethorpe : copysignint를 호출 하면 float / double로 승격되며 반환시 다시 좁혀 야합니다. 컴파일러가 프로모션을 최적화 할 수는 있지만 표준에서 보장하는 제안을 찾을 수 없습니다. 또한 copysign을 통해 signum을 구현하려면 0 사례를 수동으로 처리해야합니다. 성능 비교에이를 포함시켜야합니다.

53
첫 번째 버전은 분기가 없습니다. 사람들은 왜 표현식에 사용 된 비교가 분기를 생성하지 않는다고 생각합니까? 대부분의 아키텍처에 적용됩니다. cmove (또는 예측)가있는 프로세서 만 분기없는 코드를 생성하지만, 삼항 또는 이기면 다른 경우에도 처리합니다.
Patrick Schlüter

271

나는 그것에 대한 표준 기능을 모른다. 그래도 재미있는 방법이 있습니다.

(x > 0) - (x < 0)

보다 읽기 쉬운 방법은 다음과 같습니다.

if (x > 0) return 1;
if (x < 0) return -1;
return 0;

삼항 연산자가 마음에 들면 다음과 같이 할 수 있습니다.

(x > 0) ? 1 : ((x < 0) ? -1 : 0)

7
Mark Ransom, 귀하의 표현에 대한 결과가 잘못되었습니다 x==0.
avakar

3
@Svante : "각 연산자 <>... 지정된 관계가 참이면 1을 산출하고 거짓이면 0을 산출합니다"
Stephen Canon

11
@Svante : 정확하지 않습니다. 값 0은 "false"입니다. 다른 값은 "true"입니다. 그러나 관계형 및 등식 연산자는 항상 반환 0하거나 1표준 6.5.8 및 6.5.9를 참조하십시오. - 식의 값 a * (x == 42)중 하나입니다 0또는 a.
pmg

21
고성능 마크, C ++ 태그를 놓친 것에 놀랐습니다. 이 답변은 매우 유효하며 투표권이 없습니다. 또한 가능한 경우에도 copysign적분에 사용하지 않습니다 x.
avakar

6
누구든지 실제로 GCC / G ++ / 다른 컴파일러가 실제 플랫폼에서 어떤 코드를 생성하는지 확인 했습니까? 내 생각에 "branchless"버전은 하나 대신 두 개의 가지를 사용합니다. 비트 시프 팅은 성능면에서 훨씬 빠르며 이식성이 뛰어납니다.
Jørgen Fogh

192

copysign ()이라는 C99 수학 라이브러리 함수가 있습니다.이 함수는 한 인수의 부호와 다른 인수의 절대 값을 가져옵니다.

result = copysign(1.0, value) // double
result = copysignf(1.0, value) // float
result = copysignl(1.0, value) // long double

값의 부호에 따라 +/- 1.0의 결과를 제공합니다. 부동 소수점 0은 부호가 있습니다. (+0)은 +1을 생성하고 (-0)은 -1을 생성합니다.


57
이 중 하나를 공감하고 가장 인기있는 답변을 공감했습니다. SO 커뮤니티가 표준 라이브러리 기능을 사용하기위한 핵을 선호하는 것에 놀랐습니다. 프로그래밍의 신이 언어 표준에 익숙하지 않은 영리한 프로그래머가 사용하는 해킹을 해독하려고 모든 사람을 비난하기를 바랍니다. 그래, 나는 이것이 너무 많은 비용을 지불해야한다는 것을 알고 있지만, 나는 당신보다 다른 사람들보다 다가오는 폭풍에 직면하고 싶습니다 ...
High Performance Mark

34
이것은 가깝지만 0에 대한 잘못된 대답을 제공합니다 (적어도 Wikipedia 기사에 따르면). 그래도 좋은 제안입니다. 어쨌든 +1.
Mark Byers

4
정수를 원하거나 0에 대한 정확한 부호 결과를 원한다면 Mark Byers의 답변이 마음에 듭니다. 위의 사항을 신경 쓰지 않으면 응용 프로그램에 따라 copysign () 성능이 향상 될 수 있습니다-중요한 루프를 최적화하는 경우 두 가지를 모두 시도합니다.
다가오는 폭풍

10
1) C99는 모든 곳에서 완벽하게 지원되지는 않습니다 (VC ++ 고려). 2) 이것은 C ++ 질문이기도합니다. 이것은 좋은 대답이지만, 반대 의견도 효과적이며 더 널리 적용됩니다.
파벨 미나 에프

5
구조자! -0.0 사이에 0.0를 결정하는 방법 필요
Ólafur Waage

79

대부분의 답변이 원래의 질문을 놓친 것 같습니다.

C / C ++에 표준 부호 기능 (signum, sgn)이 있습니까?

표준 라이브러리에는 없지만 다음을 copysign통해 거의 같은 방식으로 사용할 수 있습니다copysign(1.0, arg) 에 실제 부호 함수가 boost있으며 이는 표준의 일부일 수도 있습니다.

    #include <boost/math/special_functions/sign.hpp>

    //Returns 1 if x > 0, -1 if x < 0, and 0 if x is zero.
    template <class T>
    inline int sign (const T& z);

http://www.boost.org/doc/libs/1_47_0/libs/math/doc/sf_and_dist/html/math_toolkit/utils/sign_functions.html


5
질문에 대한 답변에 가장 가까운 솔루션을 제공하므로 가장 인기있는 답변이어야합니다.
BartoszKP

지난 몇 분 동안 표준 라이브러리에 부호 기능이없는 이유가 궁금합니다. cmath 헤더에서 찾을 수있는 감마 함수보다 확실히 더 일반적으로 사용됩니다.
Taozi

4
비슷한 질문에 대해 자주 설명하는 내용은 "자신을 구현하기에 충분히 쉽다"는 것입니다. 이는 IMO가 좋은 이유가 아닙니다. 그것은 표준화, 불명확 한 경우 및 널리 사용되는 도구를 어디에 두어야 하는가의 문제에 전적으로 달려 있습니다.
Catskul

77

원래 포스터의 질문에 대한 대답은 '아니요'입니다. 표준 C ++ sgn함수 는 없습니다 .


2
@SR_ 잘못되었습니다. copysign()두 번째가 0.0이면 첫 번째 매개 변수를 0.0으로 만들지 않습니다. 다시 말해, 요한은 옳습니다.
Alexis Wilke 2016 년

29

최고 등급의 솔루션을 포함하여 위의 솔루션보다 빠릅니다.

(x < 0) ? -1 : (x > 0)

1
x는 어떤 유형입니까? 아니면 #define을 사용하고 있습니까?
Chance

3
당신의 유형은 더 빠르지 않습니다. 캐시 미스가 자주 발생합니다.
Jeffrey Drake

19
캐시 미스? 잘 모르겠습니다. 아마도 당신은 지점 오해를 의미 했습니까?
Catskul

2
정수 및 부울 유형이 혼란 스럽다는 경고가 표시됩니다!
sergiol

이것이 지점과 어떻게 빠른가요?
Nick

29

C / C ++에 표준 부호 기능 (signum, sgn)이 있습니까?

예, 정의에 따라 다릅니다.

C99 이상에는 signbit()매크로가 있습니다.<math.h>

int signbit(실제 부동 x); 매크로 반환 인수 값의 부호가 음수 인 경우에만, 제로가 아닌 값입니다. C11 §7.12.3.6
signbit


그러나 OP는 조금 다른 것을 원합니다.

음수의 경우 -1을, 양수의 경우 +1을 반환하는 함수를 원합니다. ... 수레에서 작동하는 함수.

#define signbit_p1_or_n1(x)  ((signbit(x) ?  -1 : 1)

더 깊은 :

다음과 같은 경우 게시물이 구체적이지 않습니다 x = 0.0, -0.0, +NaN, -NaN..

클래식 signum()+1on x>0, -1on x<00on으로 돌아갑니다 x==0.

많은 답변이 이미 다루어졌지만 다루지 않습니다 x = -0.0, +NaN, -NaN. 많은 수는 일반적으로 NaN (Not-a-Numbers )과 -0.0 이없는 정수 관점에 적합합니다 .

일반적인 답변은 signnum_typical() On 과 같은 기능을 -0.0, +NaN, -NaN하며 반환 0.0, 0.0, 0.0됩니다.

int signnum_typical(double x) {
  if (x > 0.0) return 1;
  if (x < 0.0) return -1;
  return 0;
}

대신, 나는이 기능을 제안합니다 : On -0.0, +NaN, -NaN, 그것은 반환합니다 -0.0, +NaN, -NaN.

double signnum_c(double x) {
  if (x > 0.0) return 1.0;
  if (x < 0.0) return -1.0;
  return x;
}

1
아, 내가 뭘했는지 이것은 Pharo Smalltalk github.com/pharo-project/pharo/pull/1835 에서 변경되었으며 부정적인 제로 및 난 행동에 대한 행동을 나타내는 일종의 표준 (IEC 60559 또는 ISO 10967)이 있는지 궁금합니다 ... javascript sign developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
aka.nice

16

분기하지 않고 할 수있는 방법이 있지만 그리 좋지는 않습니다.

sign = -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));

http://graphics.stanford.edu/~seander/bithacks.html

그 페이지에있는 흥미롭고 지나치게 많은 다른 것들도 ...


1
-1 또는 0 만 반환하는 링크를 올바르게 읽으면 -1, 0 또는 +1을 원하면 sign = (v != 0) | -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));또는 sign = (v > 0) - (v < 0);입니다.
Z boson

1
이것은 vint보다 넓지 않은 정수 타입 임을 의미합니다.
phuclv

12

부호를 테스트하는 것이 전부이면 부호 비트를 사용하십시오 (인수가 음수 부호이면 true를 리턴 함). 왜 -1 또는 +1을 반환해야하는지 잘 모르겠습니다. copysign이 더 편리하지만, 일부 플랫폼에서 음수 0 만 부분적으로 만 지원하는 음수 0의 경우 +1을 반환하는 것처럼 들립니다. 부호 비트는 아마도 true를 반환합니다.


7
부호 (x)가 필요한 수학적 응용 프로그램이 많이 있습니다. 그렇지 않으면 그냥 할 것 if (x < 0)입니다.
Chance

5

일반적으로 C / C ++에는 표준 signum 함수가 없으며 이러한 기본 함수가 없으면 이러한 언어에 대해 많은 정보를 제공합니다.

그 외에도, 나는 그러한 함수를 정의하는 올바른 접근 방식에 대한 대다수의 관점이 올바른 방식이라고 생각하며, 두 가지 중요한 경고를 고려하면 실제로 그 논쟁에 대한 논란은 논란의 여지가 없습니다.

  • 시그넘 함수는 항상 유사하게하려면, 피연산자의 타입을 반환해야 abs()하기 때문에, 함수 시그넘은 후자 든 처리되면 보통 절대 값과 곱하기 위해 사용된다. 따라서 signum 의 주요 사용 사례는 비교가 아니라 산술이며, 후자는 고가의 정수에서 부동 소수점으로의 변환을 포함하지 않아야합니다.

  • 부동 소수점 유형에는 하나의 정확한 0 값이 없습니다. +0.0은 "무한 위 0"으로, -0.0은 "무한 0 아래"로 해석 할 수 있습니다. 그것이 0을 포함하는 비교가 내부적으로 두 값을 모두 검사해야하는 이유이며, 이와 같은 표현은 x == 0.0위험 할 수 있습니다.

C와 관련하여 필자는 정수 유형을 사용하는 가장 좋은 방법은 실제로 (x > 0) - (x < 0)분기 를 사용 하지 않고 번역해야하며 3 가지 기본 연산 만 필요하므로 표현식 을 사용하는 것이라고 생각합니다 . 인수 유형과 일치하는 리턴 유형을 적용하는 인라인 함수를 가장 잘 정의하고 C11 define _Generic을 추가하여 이러한 함수를 공통 이름에 맵핑하십시오.

부동 소수점 값으로, 내가 C11을 기반으로 인라인 함수를 생각 copysignf(1.0f, x), copysign(1.0, x)그리고 copysignl(1.0l, x)길을 가야하는 것입니다, 그들은 또한있어 간단하기 때문에 가능성이 높은 지점이 없어야하고, 부동 소수점에 정수 뒷면에서 결과를 캐스팅이 필요하지 않은 추가 값. 부동 소수점 0 값의 특성, 처리 시간 고려 사항 및 부동 소수점 산술에서 올바른 -1 / +를 수신하는 것이 매우 유용하기 때문에 signum 의 부동 소수점 구현이 0을 반환하지 않을 것이라고 분명히 언급해야 합니다. 값이 0 인 경우에도 1 부호.


5

Nutshell의 C 사본은 유용한 copysign이라는 표준 함수가 있음을 보여줍니다. copysign (1.0, -2.0)은 -1.0을 반환하고 copysign (1.0, 2.0)은 +1.0을 반환하는 것처럼 보입니다.

응?


표준은 아니지만 널리 사용 가능할 수 있습니다. Microsoft는 밑줄로 시작합니다. 밑줄은 비표준 확장에 사용되는 규칙입니다. 그러나 정수로 작업 할 때 최선의 선택은 아닙니다.
Mark Ransom

5
copysign은 ISO C (C99) 및 POSIX 표준에 있습니다. 참조 opengroup.org/onlinepubs/000095399/functions/copysign.html
LHF

3
lhf가 말한 것. Visual Studio는 C 표준에 대한 참조가 아닙니다.
Stephen Canon

3

아니요, matlab과 같이 C ++에는 존재하지 않습니다. 나는 이것을 위해 내 프로그램에서 매크로를 사용합니다.

#define sign(a) ( ( (a) < 0 )  ?  -1   : ( (a) > 0 ) )

5
C ++에서는 매크로보다 템플릿을 선호해야합니다.
Ruslan

C에는 템플릿이 없습니다 ......... helloacm.com/how-to-implement-the-sgn-function-in-c
doctorlai

나는 이것이 좋은 대답이라고 생각한 다음 내 자신의 코드를보고 이것을 찾았 #define sign(x) (((x) > 0) - ((x) < 0))습니다.
Michel Rouzic

1
인라인 함수는 C에서 매크로보다 낫고 C ++ 템플릿에서는 더 좋습니다
phuclv

3

아래 과부하가 허용 된 답변은 실제로 -Wtype-limits를 트리거하지 않습니다 .

template <typename T> inline constexpr
  int signum(T x, std::false_type) {
  return T(0) < x;
}

template <typename T> inline constexpr
  int signum(T x, std::true_type) {
  return (T(0) < x) - (x < T(0));
}

template <typename T> inline constexpr
  int signum(T x) {
  return signum(x, std::is_signed<T>());
}

C ++ 11의 경우 대안이 될 수 있습니다.

template <typename T>
typename std::enable_if<std::is_unsigned<T>::value, int>::type
inline constexpr signum(T const x) {
    return T(0) < x;  
}

template <typename T>
typename std::enable_if<std::is_signed<T>::value, int>::type
inline constexpr signum(T const x) {
    return (T(0) < x) - (x < T(0));  
}

나에게는 GCC 5.3.1에 대한 경고가 발생하지 않습니다.


-Wunused-parameter경고 를 피하려면 명명되지 않은 매개 변수 만 사용하십시오.
Jonathan Wakely

그것은 실제로 매우 사실입니다. 나는 그것을 놓쳤다. 그러나 나는 C ++ 11 대안을 더 좋아합니다.
SamVanDonut

2

주제를 벗어난 것이지만 이것을 사용합니다.

template<typename T>
constexpr int sgn(const T &a, const T &b) noexcept{
    return (a > b) - (a < b);
}

template<typename T>
constexpr int sgn(const T &a) noexcept{
    return sgn(a, T(0));
}

그리고 첫 번째 함수-두 개의 인수가있는 함수는 "표준"sgn ()에서 훨씬 더 유용하다는 것을 알았습니다. 가장 일반적으로 다음과 같은 코드에서 사용되기 때문입니다.

int comp(unsigned a, unsigned b){
   return sgn( int(a) - int(b) );
}

vs.

int comp(unsigned a, unsigned b){
   return sgn(a, b);
}

부호없는 유형에 대한 캐스트가없고 추가 빼기가 없습니다.

사실 나는 sgn ()을 사용 하여이 코드 조각을 가지고있다.

template <class T>
int comp(const T &a, const T &b){
    log__("all");
    if (a < b)
        return -1;

    if (a > b)
        return +1;

    return 0;
}

inline int comp(int const a, int const b){
    log__("int");
    return a - b;
}

inline int comp(long int const a, long int const b){
    log__("long");
    return sgn(a, b);
}

1

문제는 오래되었지만 이제는 이런 종류의 원하는 기능이 있습니다. 나는 왼쪽 시프트와 12 월이 아닌 래퍼를 추가했습니다.

C99의 부호 비트를 기반으로 래퍼 함수를 ​​사용하면 원하는 동작을 정확하게 얻을 수 있습니다 (아래 코드 참조).

x의 부호가 음수인지 여부를 반환합니다.
이것은 무한대, NaN 및 0에도 적용될 수 있습니다 (0이 부호가없는 경우 양의 것으로 간주 됨)

#include <math.h>

int signValue(float a) {
    return ((!signbit(a)) << 1) - 1;
}

NB : 부호 비트의 반환 값이 1로 지정되어 있지 않기 때문에 피연산자 not ( "!")을 사용하지만 (예에서는 항상 이런 식으로 생각할 수 있지만) 음수 인 경우에는 true입니다.

반환 값
x의 부호가 음수이면 0이 아닌 값 (true)입니다. 그렇지 않으면 0 (거짓)입니다.

그런 다음 왼쪽 시프트 ( "<< 1")를 2로 곱하면 양수에 2를, 음수에 0을, 마지막으로 1을 줄이면 요청에 따라 양수와 음수 각각에 대해 1과 -1을 얻습니다. OP.


0도 긍정적일 것입니다 ... OP가 원하던 것이 아닐 수도 있습니다 ...
Antti Haapala

글쎄, 우리는 n = 0이라면 OP가 진정으로 무엇을 원했는지 알 수 없을 것이다.
Antonin GAVREL

0

허용 된 답변의 정수 솔루션은 매우 우아하지만 이중 유형에 대해 NAN을 반환 할 수 없다는 것을 귀찮게 했으므로 약간 수정했습니다.

template <typename T> double sgn(T val) {
    return double((T(0) < val) - (val < T(0)))/(val == val);
}

하드 코딩에 반대 부동 소수점 NAN을 반환합니다 NAN부호 비트가 설정되는 원인 일부 구현 에 대한 출력 있도록, val = -NAN그리고 val = NAN당신이 "원하는 경우가는 것은 (상관없이 동일 없습니다 nan이상"출력을 -nan당신이 넣을 수 있습니다 abs(val)반환하기 전에 ...)



0

분기 친화적 인 구현은 다음과 같습니다.

inline int signum(const double x) {
    if(x == 0) return 0;
    return (1 - (static_cast<int>((*reinterpret_cast<const uint64_t*>(&x)) >> 63) << 1));
}

데이터에 숫자의 절반이 0이 아닌 경우 분기 예측기는 분기 중 하나를 가장 일반적인 것으로 선택합니다. 두 가지 모두 간단한 작업 만 포함합니다.

또는 일부 컴파일러 및 CPU 아키텍처에서 완전히 분기없는 버전이 더 빠를 수 있습니다.

inline int signum(const double x) {
    return (x != 0) * 
        (1 - (static_cast<int>((*reinterpret_cast<const uint64_t*>(&x)) >> 63) << 1));
}

이것은 IEEE 754 배정도 이진 부동 소수점 형식 인 binary64에 적용 됩니다.


-1
int sign(float n)
{     
  union { float f; std::uint32_t i; } u { n };
  return 1 - ((u.i >> 31) << 1);
}

이 함수는 다음을 가정합니다.

  • 이진 32부동 소수점 숫자의 표현
  • 명명 된 공용체를 사용할 때 엄격한 앨리어싱 규칙 에 대해 예외 를 만드는 컴파일러

3
여기에는 여전히 나쁜 가정이 있습니다. 예를 들어 float의 엔디안이 정수의 엔디안임을 보장하지 않습니다. ILP64를 사용하는 아키텍처에서도 확인이 실패합니다. 실제로, 당신은 단지 다시 구현하고 있습니다 copysign. 사용하는 경우 static_assertC ++ 11이 있으며 실제로 사용할 수도 있습니다 copysign.


-3

간단하게 할 수있을 때 삼항 연산자와 if-else를 사용하는 이유

#define sgn(x) x==0 ? 0 : x/abs(x)

3
정의에는 삼항 연산자도 사용됩니다.
Martin R

예, 분명히 하나의 삼항 연산자를 사용하여 0과 0이 아닌 숫자를 구분합니다. 다른 버전에는 포지티브, 네거티브 및 제로를 구분하기위한 중첩 삼항 연산이 있습니다.
Jagreet

정수 나누기를 사용하는 것은 매우 비효율적이며 abs ()는 정수에만 해당됩니다.
Michel Rouzic 2014 년

때 정의되지 않은 동작이 가능합니다 x == INT_MIN.
chux-복권 모니카
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.