2010-06-08 2 views
7

C++에서 숫자의 부호 비트에 액세스 할 수 있기를 원합니다.C++에서 숫자의 부호 비트에 어떻게 액세스합니까?

int sign bit = number >> 31; 

음수 나에게 양수에 대한 0-1을주는 작업을 나타납니다 : 내 현재 코드는 다음과 같이 보인다. 그러나, 나는 내가 음수 -1을받을 표시되지 않습니다 : (12)가 다음

0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1100 

인 경우 -12

1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0011 

하고 이동 그것은 31 비트

0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 

을 만들 것 -1이 아닌 1입니다. 그래서 내가 그것을 옮길 때 왜 -1을 얻습니까?

+0

가능한 중복 (HTTP : // 유래. com/questions/141525/절대 - 초보자 - 가이드 - 비트 - 시프트) – msw

+0

int sign_bit = (int) (number> 0); – aviraldg

+5

[2의 보수] (http://en.wikipedia.org/wiki/Two%27s_complement#Complement_of_a_positive_number) (대부분의 최신 시스템에서 사용함)의 경우 -12가 잘못되었습니다. 그것은 0100. –

답변

11

C++에서 음수를 오른쪽으로 시프트 한 결과는 구현에 따라 정의됩니다. 따라서 귀하의 -12을 특정 플랫폼에서 올바르게 가져와야하는 것을 아는 사람은 아무도 없습니다. 당신은 그것이 위의 것 (1)을 만들어야한다고 생각하는데, 나는 그것이 모든 것을 쉽게 만들 수 있다고 말합니다. -1입니다. 후자는 부호 확장 이동이라고합니다. 부호 확장 시프트에서 부호 비트는 오른쪽으로 복사되지만 그 자리에서 절대로 이동하지 않습니다.

부호 비트의 값이 관심이 있다면, 시프트 등 비트 연산을 사용하여 시간을 낭비하지 마십시오. 숫자를 0과 비교하여 음수인지 아닌지 확인하십시오.

+1

이것은 정말로 오래된 게시물이지만 다른 것을 찾고있는 동안 나는 이것을 보았습니다. 나는 당신이 여기서 말하고있는 것에 대체로 동의합니다. 그러나 그의 질문에 그가 작성한 코드의 결과에 기여했을 수도있는 몇 가지 가정이 있습니다. 이것은 비트 시프 팅을 독립적으로 사용하거나 비트 마스크를 사용하여 부호 비트를 검사하는 것만으로 수행 할 수 있습니다. –

+0

이것은 -0.0을 +0.0과 구별하지 않습니다. 이를 위해 부호 비트에 액세스해야합니다. 존의 대답을보십시오. –

+0

@NeilG 질문의 텍스트를 바탕으로 정수에 관해 묻는 것 같습니다. –

24

어떨까요?

int sign = number < 0;

2

>> 오퍼레이터는 수치의 부호를 보존 arithmetic shift을 수행한다.

+4

을 끝내야합니다. 어떤 종류의 이동이'>> '연산자에 의해 수행되는지는 구현에 의해 정의됩니다. 어떤 종류의 교대 일 수 있습니다. – AnT

+0

@AndreyT : ">> 연산자가 산술 이동을 수행하고있다"고 말했고, 이것이 OP의 설명으로 판단 할 때이 경우 정확하게 수행하고 있습니다. I *는''''연산자가 항상 산술 이동을 수행하지 않는다는 것을 알았습니다. 아마 내가 더 분명해야하지만, 어느 쪽이든, 내 대답은 downvote받을 가치가 있다고 생각하지 않습니다. – LukeH

+2

@Downvoters : 자신을 정당화하십시오. 나는 OP의 문제가 무엇인지 정확히 설명했다. ">> 연산자는 항상 산술 시프트를 수행합니다"; 나는이 특별한 경우에 * 연산자가 무엇을하는지 정확하게 설명했다. – LukeH

7

부호가있는 정수가 이동하기 때문에. 부호없는 정수로 캐스팅하기 :

int sign_bit = ((unsigned int)number) >> 31; 
4

정수의 경우, number < 0을 테스트하십시오.

부동 소수점 숫자의 경우 0에 부호가 있음을 고려해야 할 수도 있습니다. 즉, +0.0과 구별되는 -0.0이 있습니다. 두 가지를 구별하려면 std::signbit을 사용하고 싶습니다.

1
bool signbit(double x) 
{ 
    return 1.0/x != 1.0/fabs(x); 
} 

내 솔루션은 +/- 0을 지원합니다. 당신은 입력과 출력으로 부울 값으로 float 값을 얻을 cmath 라이브러리

#include <cmath> 

를 사용하고

std::cout << std::signbit(num); 

이 기능처럼 사용할 수 있습니다

2

.예컨대

true for negative 
false for positive 

표준 : COUT < < signbit 표준 : (1);

는이 라인의 출력이 동일하지 제로

std::cout << std::signbit(-0.0); // 512 (true) 
std::cout << std::signbit(+0.0); // 0 (false) 

에 대해 조심해야

하지만 잠시

이 기능을 사용하면 0으로 출력 (거짓)을 제공 할 것입니다. 줄

float x = +0.01; 
std::cout << (x >= 0 ? (x == 0 ? 0 : 1) : -1); 

:

은 당신이 사용할 수있는이 문제를 제거하려면 [? 비트가 쉬프트 절대 초보자 가이드]의

0 for 0 
1 for positive 
-1 for negative 
-1
bool signbit(double x) 
{ 
    return (__int64)x & 0x8000000000000000LL != 0LL; 
} 

bool signbit(float x) 
{ 
    return (__int32)x & 0x80000000 != 0; 
} 
+0

은'x '가'__int64'의 범위를 벗어나면 정의되지 않은 동작을합니다. –

관련 문제