programing

비트 와이즈 연산자를 사용하여 숫자가 양수인지 음수인지 확인

mailnote 2023. 9. 28. 08:39
반응형

비트 와이즈 연산자를 사용하여 숫자가 양수인지 음수인지 확인

나는 비트 와이즈 연산자를 사용하여 숫자가 홀수/짝수인지 확인할 수 있습니다.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

반응형