it-swarm-ko.tech

두 정수가 동일한 부호를 갖는지 확인하는 가장 간단한 방법은 무엇입니까?

두 정수가 동일한 부호를 갖는지 확인하는 가장 간단한 방법은 무엇입니까? 이것을하기위한 짧은 비트 트릭이 있습니까?

60
Gerber

다음은 정수 크기에 의존하지 않거나 오버플로 문제가있는 C/C++에서 작동하는 버전입니다 (예 : x * y> = 0이 작동하지 않음)

bool SameSign(int x, int y)
{
    return (x >= 0) ^ (y < 0);
}

물론, 당신은 괴짜와 템플릿을 할 수 있습니다 :

template <typename valueType>
bool SameSign(typename valueType x, typename valueType y)
{
    return (x >= 0) ^ (y < 0);
}

참고 : 배타적 또는 사용하기 때문에 부호가 같을 때 LHS와 RHS가 다르기를 원하므로 0에 대한 다른 검사입니다.

47
Torlack

무슨 일이야

return ((x<0) == (y<0));  

?

203
Rik
(a ^ b) >= 0

부호가 같으면 1로 평가하고 그렇지 않으면 0으로 평가합니다.

23
Chris Jobson

정수의 부호를 결정하는 비트 트릭에주의를 기울여야합니다. 그러면 숫자가 내부적으로 표현되는 방식에 대해 가정해야합니다.

시간의 거의 100 %에서 정수는 two 's compliment 로 저장되지만 특정 저장 형식을 보장하는 데이터 유형을 사용하지 않는 한 시스템 내부에 대해 가정하는 것은 좋지 않습니다.

2의 칭찬에서 정수의 마지막 (가장 왼쪽) 비트를 확인하여 음수인지 확인하면이 두 비트 만 비교할 수 있습니다. 이것은 0이 양수와 같은 부호를 가지게됨을 의미하며, 이는 대부분의 언어로 구현 된 부호 함수와 상충됩니다.

개인적으로, 나는 당신이 선택한 언어의 부호 기능을 사용하고 싶습니다. 이와 같은 계산에 성능 문제가있을 가능성은 거의 없습니다.

12
SpoonMeiser

32 비트 정수 가정 :

bool same = ((x ^ y) >> 31) != 1;

약간 더 간결합니다 :

bool same = !((x ^ y) >> 31);
6
Patrick

나는 "비트 트릭"과 "가장 단순한"이 동의어라고 생각하지 않습니다. 부호있는 32 비트 정수를 가정하고 많은 답변을 봅니다 (그러나 would 부호없는 것을 요청하는 것은 어리 석습니다). 부동 소수점 값에 적용되는지 확실하지 않습니다.

"가장 간단한"점검은 두 값이 0과 어떻게 비교되는지 비교하는 것 같습니다. 유형을 비교할 수 있다고 가정하면 매우 일반적입니다.

bool compare(T left, T right)
{
    return (left < 0) == (right < 0);
}

표시가 반대이면 거짓이됩니다. 표시가 동일하면 사실입니다.

5
OwenP

(정수 1 * 정수 2)> 0

두 정수가 부호를 공유하면 곱셈의 결과는 항상 양수입니다.

0을 무엇이든 상관없이 같은 부호로 취급하려면> = 0으로 만들 수도 있습니다.

4
Benjamin Autin

두 개가 산술을 보완한다고 가정하면 ( http://en.wikipedia.org/wiki/Two_complement ) :

inline bool same_sign(int x, int y) {
    return (x^y) >= 0;
}

최적화 된 최신 프로세서에서는 명령이 2 개, 1ns 미만이 될 수 있습니다.

2가 산술을 보완한다고 가정하지 않음 :

inline bool same_sign(int x, int y) {
    return (x<0) == (y<0);
}

이 작업에는 하나 또는 두 개의 추가 지침이 필요할 수 있으며 시간이 조금 더 걸립니다.

곱셈을 사용하는 것은 오버플로에 취약하기 때문에 나쁜 생각입니다.

4
user10315

(x * y)> 0 인 경우 ...

0이 아닌 것으로 가정합니다.

3
Yes - that Jake.

기술적으로, 현대적인 아키텍처에서도 비트 솔루션은 곱셈보다 훨씬 효율적입니다. 저장하는주기는 약 3주기에 불과하지만 "페니 저장"에 대해 그들이 말하는 것을 알고 있습니다.

2
Daniel Spiewak

분기없는 C 버전 :

int sameSign(int a, int b) {
    return ~(a^b) & (1<<(sizeof(int)*8-1));
}

정수 타입을위한 C++ 템플릿 :

template <typename T> T sameSign(T a, T b) {
    return ~(a^b) & (1<<(sizeof(T)*8-1));
}
1
CAFxX

내 머리 꼭대기에서.

int mask = 1 << 31;
(a & mask) ^ (b & mask) < 0;
1
Daniel Spiewak

2의 보수 산술을 가진 int 크기에 관계없이 :

#define SIGNBIT (~((unsigned int)-1 >> 1))
if ((x & SIGNBIT) == (y & SIGNBIT))
    // signs are the same
1
Mark Ransom

32 비트 가정

if(((x^y) & 0x80000000) == 0)

... 오버플로로 인해 if(x*y>0) 답변이 잘못되었습니다

1
ugasoft

(a * b <0) 부호가 다른 경우 부호가 동일하거나 a 또는 b가 0 인 경우

0
dogfish

대부분의 기계 표현에서 대학 시절을 생각하면 숫자가 음수이면 정수의 가장 왼쪽 비트가 1이 아니고 양수이면 0이 아닌가?

나는 이것이 다소 기계 의존적이라고 생각한다.

0
Dana

int same_sign =! ((x >> 31) ^ (y >> 31));

if (same_sign) ... 그렇지 않으면 ...

0
andrew

다음과 같이 std :: signbit 을 사용하는 것이 좋습니다.

std::signbit(firstNumber) == std::signbit(secondNumber);

또한 다른 기본 유형 (double, float, char 등)도 지원합니다.

0
ashiquzzaman33