두 정수의 부호가 같은지 확인하는 가장 간단한 방법은 무엇입니까?
두 정수의 부호가 같은지 확인하는 가장 간단한 방법은 무엇입니까? 이 작업을 수행하는 짧은 비트 트릭이 있습니까?
다음은 정수 크기에 의존하지 않거나 오버플로 문제가있는 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);
}
참고 : 배타적 or를 사용하고 있으므로 부호가 같을 때 LHS와 RHS가 다르기 때문에 0에 대해 다른 검사를 수행해야합니다.
뭐가 잘못 됐어
return ((x<0) == (y<0));
?
(a ^ b) >= 0
부호가 같으면 1, 그렇지 않으면 0으로 평가됩니다.
정수의 부호를 결정하는 비트 트릭에 대해주의해야합니다. 그런 다음 해당 숫자가 내부적으로 어떻게 표현되는지에 대해 가정해야하기 때문입니다.
거의 100 %의 경우 정수는 2의 칭찬 으로 저장 되지만 특정 저장 형식을 보장하는 데이터 유형을 사용하지 않는 한 시스템 내부에 대해 가정하는 것은 좋지 않습니다.
2의 칭찬에서 정수의 마지막 (가장 왼쪽) 비트를 확인하여 음수인지 확인할 수 있으므로이 두 비트 만 비교할 수 있습니다. 이것은 0이 양수와 동일한 부호를 가질 것이라는 것을 의미하며, 이는 대부분의 언어에서 구현 된 부호 함수와 상충됩니다.
개인적으로 저는 당신이 선택한 언어의 기호 기능을 사용하고 싶습니다. 이와 같은 계산에 성능 문제가있을 가능성은 거의 없습니다.
32 비트 정수 가정 :
bool same = ((x ^ y) >> 31) != 1;
약간 더 간결 :
bool same = !((x ^ y) >> 31);
"비트 트릭"과 "가장 단순"이 동의어라고 생각할지 모르겠습니다. 나는 (비록 32 비트 정수에 서명 가정합니다 답변을 많이 볼 것 서명을 요청하는 바보를); 부동 소수점 값에 적용되는지 확실하지 않습니다.
"가장 간단한"검사는 두 값이 0과 비교되는 방식을 비교하는 것 같습니다. 유형을 비교할 수 있다고 가정하면 매우 일반적입니다.
bool compare(T left, T right)
{
return (left < 0) == (right < 0);
}
표시가 반대이면 거짓입니다. 징후가 같으면 사실입니다.
(integer1 * integer2)> 0
두 정수가 부호를 공유 할 때 곱셈의 결과는 항상 양수이기 때문입니다.
어떤 경우에도 0을 동일한 부호로 취급하려면> = 0으로 만들 수도 있습니다.
2가 산술을 보완한다고 가정합니다 ( 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);
}
이것은 하나 또는 두 개의 추가 지침이 필요할 수 있으며 조금 더 오래 걸릴 수 있습니다.
곱셈을 사용하는 것은 오버플로에 취약하기 때문에 나쁜 생각입니다.
만약 (x * y)> 0 ...
0이 아닌 것으로 가정합니다.
기술적 인 측면에서 보면, 현대적인 아키텍처에서도 조금 뒤틀린 솔루션이 곱셈보다 훨씬 더 효율적일 것입니다. 당신이 절약하는 것은 약 3주기 뿐이지 만 "페니 절약"에 대해 그들이 말하는 것을 알고 있습니다 ...
내 머리 꼭대기에서 ...
int mask = 1 << 31;
(a & mask) ^ (b & mask) < 0;
분기없는 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));
}
2의 보수 산술을 사용하는 모든 int 크기의 경우 :
#define SIGNBIT (~((unsigned int)-1 >> 1))
if ((x & SIGNBIT) == (y & SIGNBIT))
// signs are the same
32 비트 가정
if(((x^y) & 0x80000000) == 0)
... the answer if(x*y>0)
is bad due to overflow
if (a*b < 0) sign is different, else sign is the same (or a or b is zero)
Thinking back to my university days, in most machine representations, isn't the left-most bit of a integer a 1 when the number is negative, and 0 when it's positive?
I imagine this is rather machine-dependent, though.
int same_sign = !( (x >> 31) ^ (y >> 31) );
if ( same_sign ) ... else ...
Better way using std::signbit as follows:
std::signbit(firstNumber) == std::signbit(secondNumber);
It also support other basic types (double
, float
, char
etc).
참고URL : https://stackoverflow.com/questions/66882/simplest-way-to-check-if-two-integers-have-same-sign
'developer tip' 카테고리의 다른 글
수학 함수 나 로그 함수없이 숫자가 2의 거듭 제곱인지 확인 (0) | 2020.12.02 |
---|---|
'if'문에는 항상 'else'절이 있어야합니까? (0) | 2020.12.02 |
가장 좋아하는 C ++ 코딩 스타일 관용구는 무엇입니까? (0) | 2020.12.02 |
UITabBar 높이 변경 (0) | 2020.12.02 |
UITabBar 높이 변경 (0) | 2020.12.02 |