CHAR_BIT는 무엇입니까?


91

http://graphics.stanford.edu/~seander/bithacks.html 에서 분기하지 않고 정수 절대 값 (abs)을 계산하는 코드를 인용합니다 .

int v;           // we want to find the absolute value of v
unsigned int r;  // the result goes here 
int const mask = v >> sizeof(int) * CHAR_BIT - 1;

r = (v + mask) ^ mask;

특허받은 변형 :

r = (v ^ mask) - mask;

무엇 CHAR_BIT이며 어떻게 사용합니까?

답변:


-1

이 코드는 서명 된 형식에 대한 오른쪽 비트 시프트의 구현 정의 동작에 따라 다릅니다. gcc는 항상 정상적인 동작 (sign-bit-extension)을 제공 할 것을 약속하지만 ISO C는 구현이 상위 비트를 0으로 채울 수 있도록합니다.

이 문제를 해결하는 한 가지 방법 :

#ifdef HAVE_SIGN_EXTENDING_BITSHIFT
int const mask = v >> sizeof(int) * CHAR_BIT - 1;
#else
int const mask = -((unsigned)v >> sizeof(int) * CHAR_BIT - 1);
#endif

귀하 Makefile또는 config.h등 정의 할 수 있습니다 HAVE_SIGN_EXTENDING_BITSHIFT플랫폼에 따라 빌드시.


120
나는 이것이 매우 흥미로운 코멘트 임에도 불구하고 질문에 대답하지 않기 때문에 이것이 어떻게 받아 들여지는 대답이 될 수 있는지 이해하지 못합니다.
qdii

15
@Mauris : 누군가 질문을 편집하고 하위 질문을 질문 제목으로 승격했습니다. 원래 제목은 끔찍했지만 OP의 질문은 인용 된 비트 해킹 코드가 어떻게 작동하는지에 관한 것이었고, "적어도 이식 가능하지 않은데, 여기에 이유"가 유용한 답변입니다.
R .. GitHub STOP HELPING ICE

12
아, 이해합니다. 안타깝게도이 질문은 "무엇입니까 CHAR_BIT?" 에 대한 Google 검색 결과에서 매우 높게 표시됩니다. , 원래 질문이 아니더라도. :( 귀하의 설명을 감안할 때이 답변을 작성한 이유를 이해하지만 후손에게는 (a) 답변을 제거하고 질문에 대한 주석으로 다시 작성하여 @ AraK 's가 맨 위에 표시되도록하는 것이 더 유용 할 수 있습니다. (b) 질문의 현재 제목에 대한 답변이되도록 답변을 편집합니다
Lynn

1
OP의 원래 질문과 편집자의 해석의 의도 차이로 인해 원래 요청의 성격이 무의식적으로 변경된 것처럼 보입니다. 두 질문 (원본 및 편집) 모두 장점이 있지만이 불일치를 해결해야합니다. 나는 지금 질문합니다 :이 답변을 위키에 추가 할 수 있습니까? 이것은 원래 질문과 관련이 없지만 이러한 유형의 정보를 검색하는 사람들에게 도움이 될 수 있습니다. 그런 다음 dato datuashvili의 원래 요청에 맞게 질문을 다시 편집 할 수 있습니다. 관심있는 독자 ...

2
이 질문의 역사를 살펴 보았고 원래 질문은 실제로 코드가 어떻게 작동하는지 묻지 않습니다. 편집자가 제목에 올린 질문은 거기에있는 유일한 실제 질문입니다.
plugwash

224

CHAR_BIT의 비트 수입니다 char. 요즘 거의 모든 아키텍처가 바이트 당 8 비트를 사용하지만 항상 그런 것은 아닙니다. 예전에는 7 비트 바이트를 사용하던 일부 오래된 머신이 있습니다.

에서 찾을 수 있습니다 <limits.h>.


3
일부 DSP에는 10 비트 이상이 있습니다.
Juri Robl

64
C는 CHAR_BIT>=8단일 유형 크기 (종종 32 비트) 만있는 DSP에 대해 훨씬 더 큰 값을 요구 하고 허용 합니다 . POSIX에는 CHAR_BIT==8. 일반적으로 인터넷에 연결되거나 텍스트 데이터를 외부 세계와 교환 할 가능성이있는 모든 다중 사용자 / 멀티 태스킹 서버 지향 또는 대화 형 사용 지향 아키텍처를 가정 할 수 있습니다 CHAR_BIT==8.
R .. GitHub의 STOP 돕기 ICE

6
@caf : 아니, 그것은 C99이 유형을 필요로한다는 것이다 int8_tuint8_t존재. 따라서 너비 8 유형이 존재합니다. sizeof모든 유형이 sizeof char실제로 호환 sizeof int8_t되어야하므로 1이어야합니다. 그래서 CHAR_BIT == 8. 나는 여기에 obeservation 주위에 뭔가를 작성했습니다 : gustedt.wordpress.com/2010/06/01/how-many-bits-has-a-byte
옌스 Gustedt

22
@Jens Gustedt : C99 사양의 섹션을 인용하십시오. 정확한 너비 정수 유형 중 C99 사양은 "이러한 유형은 선택 사항입니다."라고 말합니다. (7.18.1.1/3) 최소 너비 및 가장 빠른 너비 유형이 필요합니다.
jamesdlin

3
@jamesdlin & caf : 죄송합니다. 예, 내가 언급 한 요구 사항은 실제로 POSIX에서 stdint.h. 따라서 해당 표준의 특정 버전을 참조하지 않고 ISO C 표준에 대한 확장으로 표시됩니다 . 내 잘못이야.
Jens Gustedt 2010

2

원래 질문의 명시 적 질문 (CHAR_BIT은 무엇인가)과 암시 적 질문 (이 작동 방식)에 모두 답하려고합니다.


C 및 C ++의 문자는 C 프로그램이 처리 할 수있는 가장 작은 메모리 단위를 나타냅니다. *

C 및 C ++의 CHAR_BIT는 문자의 비트 수를 나타냅니다. char 유형에 대한 다른 요구 사항으로 인해 항상 8 이상이어야합니다. 실제로 모든 최신 범용 컴퓨터에서는 정확히 8 개이지만 일부 역사적 또는 전문 시스템은 더 높은 값을 가질 수 있습니다.

Java는 CHAR_BIT 또는 sizeof와 동등하지 않으며 Java의 모든 기본 유형이 고정 크기이고 객체의 내부 구조가 프로그래머에게 불투명하므로 필요하지 않습니다. 이 코드를 Java로 변환하는 경우 "sizeof (int) * CHAR_BIT-1"을 고정 값 31로 간단히 바꿀 수 있습니다.

이 특정 코드에서는 int의 비트 수를 계산하는 데 사용됩니다. 이 계산은 int 유형에 패딩 비트가 포함되어 있지 않다고 가정합니다.

컴파일러가 부호있는 숫자의 비트 시프트에서 부호 확장을 선택하고 시스템이 음수에 대해 2의 보수 표현을 사용한다고 가정하면 "MASK"는 양수 또는 0 값에 대해 0이고 음수 값에 대해 -1이됩니다.

2의 보수 수를 부정하려면 비트 not을 수행 한 다음 1을 더해야합니다. 동등하게 우리는 1을 뺀 다음 비트로 부정 할 수 있습니다.

다시 2의 보수 표현 -1이 모두 1로 표현된다고 가정하면 배타적 또는 -1은 비트 부정과 동등합니다.

따라서 v가 0이면 숫자는 그대로 남아 있고 v가 1이면 부정됩니다.

주의해야 할 점은 C 및 C ++의 서명 된 오버플로가 정의되지 않은 동작입니다. 따라서 가장 부정적인 값에이 ABS 구현을 사용하면 정의되지 않은 동작이 발생합니다. 프로그램의 마지막 줄이 unsigned int로 평가되도록 캐스트를 추가하여이 문제를 해결할 수 있습니다.

* 일반적으로 하드웨어가 처리 할 수있는 가장 작은 메모리 단위와 동일하지는 않습니다. 구현은 잠재적으로 하드웨어 주소 지정 가능 메모리의 여러 단위를 프로그램 주소 지정 가능 메모리의 한 단위로 결합하거나 하드웨어 주소 지정 가능 메모리의 한 단위를 프로그램 추가 가능 메모리의 여러 단위로 분할 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.