비트 와이즈 연산자를 사용하여 숫자가 양수인지 음수인지 확인
나는 비트 와이즈 연산자를 사용하여 숫자가 홀수/짝수인지 확인할 수 있습니다.if/ternary 등의 조건문/연산자를 사용하지 않고 숫자가 양수/0/음수인지 확인할 수 있습니까?
비트 와이즈 연산자와 C 또는 C++에서 어떤 트릭을 사용하여 같은 작업을 수행할 수 있습니까?
if/ternary 등의 조건문/연산자를 사용하지 않고 숫자가 양수/0/음수인지 확인할 수 있습니까?
물론입니다.
bool is_positive = number > 0;
bool is_negative = number < 0;
bool is_zero = number == 0;
부호가 있는 정수(바이트, 길이 등)에 높은 비트가 설정되어 있지만 부동 소수점 번호는 설정되어 있지 않으면 해당 숫자는 음수가 됩니다.
int x = -2300; // assuming a 32-bit int
if ((x & 0x80000000) != 0)
{
// number is negative
}
추가됨:
당신은 어떠한 조건도 사용하고 싶지 않다고 말했습니다.당신이 할 수 있다고 생각합니다.
int isNegative = (x & 0x80000000);
그리고 나중에 테스트해 볼 수 있습니다.if (isNegative).
아니면, 당신이 사용할 수도 있고, 일은 당신을 위해 끝납니다.
내 생각엔 후드 밑에서math.h구현은 효율적인 비트 와이즈 체크(원래 목표를 해결하는 possibly)입니다.
참조 : http://en.cppreference.com/w/cpp/numeric/math/signbit
Bit Twiddling Hacks 페이지에 자세한 논의가 있습니다.
int v; // we want to find the sign of v
int sign; // the result goes here
// CHAR_BIT is the number of bits per byte (normally 8).
sign = -(v < 0); // if v < 0 then -1, else 0.
// or, to avoid branching on CPUs with flag registers (IA32):
sign = -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));
// or, for one less instruction (but not portable):
sign = v >> (sizeof(int) * CHAR_BIT - 1);
// The last expression above evaluates to sign = v >> 31 for 32-bit integers.
// This is one operation faster than the obvious way, sign = -(v < 0). This
// trick works because when signed integers are shifted right, the value of the
// far left bit is copied to the other bits. The far left bit is 1 when the value
// is negative and 0 otherwise; all 1 bits gives -1. Unfortunately, this behavior
// is architecture-specific.
// Alternatively, if you prefer the result be either -1 or +1, then use:
sign = +1 | (v >> (sizeof(int) * CHAR_BIT - 1)); // if v < 0 then -1, else +1
// On the other hand, if you prefer the result be either -1, 0, or +1, then use:
sign = (v != 0) | -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));
// Or, for more speed but less portability:
sign = (v != 0) | (v >> (sizeof(int) * CHAR_BIT - 1)); // -1, 0, or +1
// Or, for portability, brevity, and (perhaps) speed:
sign = (v > 0) - (v < 0); // -1, 0, or +1
// If instead you want to know if something is non-negative, resulting in +1
// or else 0, then use:
sign = 1 ^ ((unsigned int)v >> (sizeof(int) * CHAR_BIT - 1)); // if v < 0 then 0, else 1
// Caveat: On March 7, 2003, Angus Duggan pointed out that the 1989 ANSI C
// specification leaves the result of signed right-shift implementation-defined,
// so on some systems this hack might not work. For greater portability, Toby
// Speight suggested on September 28, 2005 that CHAR_BIT be used here and
// throughout rather than assuming bytes were 8 bits long. Angus recommended
// the more portable versions above, involving casting on March 4, 2006.
// Rohit Garg suggested the version for non-negative integers on September 12, 2009.
#include<stdio.h>
void main()
{
int n; // assuming int to be 32 bit long
//shift it right 31 times so that MSB comes to LSB's position
//and then and it with 0x1
if ((n>>31) & 0x1 == 1) {
printf("negative number\n");
} else {
printf("positive number\n");
}
getch();
}
부호가 있는 정수와 부동 소수점은 일반적으로 부호를 저장할 때 최상위 비트를 사용하므로 크기를 알면 최상위 비트에서 정보를 추출할 수 있습니다.
이 정보를 사용하기 위해서는 일종의 비교가 필요하고 프로세서가 부정적인지 여부를 테스트하는 것이 0이 아닌지 테스트하는 것만큼 쉽기 때문에 이 작업을 수행하는 데 이점이 거의 없습니다.ARM 프로세서에 문제가 있는 경우, 가장 의미 있는 비트를 확인하는 것이 부정적인지 여부를 확인하는 것보다 일반적으로 더 비용이 많이 듭니다.
그것은 아주 간단합니다.
쉽게 할 수 있습니다.
return ((!!x) | (x >> 31));
돌아오다
- 양수일 경우 1,
- -1 음의 경우, 그리고
- 0 대 0
이것은 C의 비트 연산으로는 휴대용 방식으로는 할 수 없습니다.표준에서 허용하는 부호가 있는 정수 유형에 대한 표현은 의심할 수 있는 것보다 훨씬 이상할 수 있습니다.특히 부호 비트가 켜져 있고 그렇지 않으면 0인 값은 부호가 있는 유형이나 부호가 없는 유형에 대해 허용되는 값이 아니라 두 유형 모두에 대해 소위 트랩 표현일 필요가 있습니다.
따라서 비트 연산자를 사용하는 모든 계산은 정의되지 않은 동작을 초래하는 결과를 가져올 수 있습니다.
은 사실 하듯이, 입니다.<아니면>어떤 실용적인 맥락에서도 충분해야 하고, 더 효율적이고, 읽기 쉽도록...그러니까 그냥 그렇게 해요.
// if (x < 0) return -1
// else if (x == 0) return 0
// else return 1
int sign(int x) {
// x_is_not_zero = 0 if x is 0 else x_is_not_zero = 1
int x_is_not_zero = (( x | (~x + 1)) >> 31) & 0x1;
return (x & 0x01 << 31) >> 31 | x_is_not_zero; // for minux x, don't care the last operand
}
이게 바로 당신이 말한 것입니다!
이 오래된 질문에 대한 C++11 관련 업데이트 내용입니다.std::signbit도 고려해 볼만합니다.
-O3 최적화와 함께 gcc 7.364비트를 사용하는 컴파일러 탐색기의 경우, 이 코드
bool s1(double d)
{
return d < 0.0;
}
생성하다
s1(double):
pxor xmm1, xmm1
ucomisd xmm1, xmm0
seta al
ret
그리고 이 코드는
bool s2(double d)
{
return std::signbit(d);
}
생성하다
s2(double):
movmskpd eax, xmm0
and eax, 1
ret
속도 차이가 있는지 확인하려면 프로파일링을 해야 하지만, 부호비트 버전에서는 opcode를 1개 덜 사용합니다.
정수 크기(16비트 int 가정)가 확실한 경우:
bool is_negative = (unsigned) signed_int_value >> 15;
정수의 크기를 확신할 수 없는 경우:
bool is_negative = (unsigned) signed_int_value >> (sizeof(int)*8)-1; //where 8 is bits
unsigned키워드는 선택사항입니다.
if( (num>>sizeof(int)*8 - 1) == 0 )
// number is positive
else
// number is negative
값이 0이면 숫자는 양수이고, 그 외에는 음수입니다.
어떤 숫자가 양수인지 음수인지 알아내는 더 간단한 방법: 숫자가 [x * (-1)] > x인지 확인하게 하고, 참 x가 음수이면 양수가 됩니다.
가장 유의한 비트를 보면 음/음이 아닌 것을 구별할 수 있습니다.부호가 있는 정수에 대한 모든 표현에서 숫자가 음수이면 해당 비트가 1로 설정됩니다.
0에 대한 직접적인 검정을 제외하고는 0과 양을 구별하는 검정이 없습니다.
음성 판정을 받기 위해서는
#define IS_NEGATIVE(x) ((x) & (1U << ((sizeof(x)*CHAR_BIT)-1)))
가 이라고 합니다.a=10(양성) 만약 a a0의 시간을 줍니다.
즉,
10>>10 == 0
할 수 일 에는 a=-10성):
-10>>-10 == -1
그래서 당신은 그것들을 결합할 수 있습니다.if:
if(!(a>>a))
print number is positive
else
print no. is negative
#include<stdio.h>
int checksign(int n)
{
return (n >= 0 && (n & (1<<32-1)) >=0);
}
void main()
{
int num = 11;
if(checksign(num))
{
printf("Unsigned number");
}
else
{
printf("signed Number");
}
}
다음 조건 없이:
string pole[2] = {"+", "-"};
long long x;
while (true){
cin >> x;
cout << pole[x/-((x*(-1))-1)] << "\n\n";
}
(0에 대해 작동하지 않음)
if(n & (1<<31))
{
printf("Negative number");
}
else{
printf("positive number");
}
n개의 숫자 중에서 가장 의미 있는 첫번째 비트를 확인한 다음 값이 1이고 그 값이 참이고 그 값이 음수이고 양수가 아니면 작업을 수행합니다.
언급URL : https://stackoverflow.com/questions/3779202/checking-whether-a-number-is-positive-or-negative-using-bitwise-operators
'programing' 카테고리의 다른 글
| 효과가 끝날 때까지 jQuery를 기다리게 하는 방법은? (0) | 2023.09.28 |
|---|---|
| DBD 설치 방법:: 딸기 펄 속의 오라클 (0) | 2023.09.28 |
| 매개 변수로 배열 포인터를 함수에 전달 (0) | 2023.09.28 |
| Galera 노드가 떨어지면 커밋에서 '잠금을 시도할 때 데드락 발견 (0) | 2023.09.28 |
| Excel VBA: 배열 변수의 변형 (0) | 2023.09.28 |