이진수로 작업해야합니다.
나는 쓰기를 시도했다 :
const x = 00010000;
그러나 작동하지 않았습니다.
와 같은 값을 가진 16 진수를 사용할 수 있다는 00010000
것을 알고 있지만 이진 숫자에 대한 C ++에 유형이 있는지, 그렇지 않은 경우 내 문제에 대한 다른 해결책이 있습니까?
답변
C ++ 0x를 기다리는 동안 사용할BOOST_BINARY
수 있습니다 . 🙂 BOOST_BINARY
논란의 여지없이 C 프로그램에서도 사용할 수있는 한 템플릿 구현에 비해 이점이 있습니다 (100 % 전 처리기 구동).
대화를하기 위해 (즉, 이진 형식으로 숫자를 인쇄하기 위해) 이식 불가능한 itoa
함수 를 사용하거나 직접 구현할 수 있습니다 .
불행히도 STL 스트림을 사용하여 기본 2 형식을 수행 할 수는 없지만 ( setbase
기준 8, 10 및 16 만 존중 하므로 ) 버전을 사용 하거나 (보다 간결하지만 약간 덜 효율적 임) 버전을 사용할 수 있습니다 .std::string
itoa
std::bitset
#include <boost/utility/binary.hpp>
#include <stdio.h>
#include <stdlib.h>
#include <bitset>
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
unsigned short b = BOOST_BINARY( 10010 );
char buf[sizeof(b)*8+1];
printf("hex: %04x, dec: %u, oct: %06o, bin: %16s\n", b, b, b, itoa(b, buf, 2));
cout << setfill('0') <<
"hex: " << hex << setw(4) << b << ", " <<
"dec: " << dec << b << ", " <<
"oct: " << oct << setw(6) << b << ", " <<
"bin: " << bitset< 16 >(b) << endl;
return 0;
}
생산 :
hex: 0012, dec: 18, oct: 000022, bin: 10010
hex: 0012, dec: 18, oct: 000022, bin: 0000000000010010
흥미로운 토론을 위해 Herb Sutter의 Manor Farm 의 The String Formatters를 읽으십시오 .
답변
답변
이진 리터럴을 사용할 수 있습니다. 그것들은 C ++ 14로 표준화되었습니다. 예를 들어
int x = 0b11000;
GCC 지원
GCC 지원은 GCC 4.3에서 시작되었습니다 (참조 https://gcc.gnu.org/gcc-4.3/changes.html을 C 언어 제품군 확장으로) (참조 https://gcc.gnu.org/onlinedocs/gcc/ C-Extensions.html # C-Extensions )이지만 GCC 4.9부터는 이제 C ++ 14 기능 또는 확장으로 인식됩니다 ( GCC 이진 리터럴과 C ++ 14의 차이점은 무엇입니까? 참조 ).
Visual Studio에서 지원
Visual Studio 2015 Preview에서 시작된 Visual Studio 지원 ( https://www.visualstudio.com/news/vs2015-preview-vs#C++ 참조) ) .
답변
template<unsigned long N>
struct bin {
enum { value = (N%10)+2*bin<N/10>::value };
} ;
template<>
struct bin<0> {
enum { value = 0 };
} ;
// ...
std::cout << bin<1000>::value << '\n';
리터럴의 가장 왼쪽 숫자는 여전히 1이어야하지만 그럼에도 불구하고.
답변
일부 컴파일러 (보통 마이크로 컨트롤러 용 컴파일러 )에는 대부분의 컴파일러 (C / C ++ 표준)에 이러한 기능이 없지만 대부분의 컴파일러 (C / C ++ 표준)에는 해당되지 않지만, 숫자 앞에 접두사 “0b …”로 리터럴 이진 숫자를 인식하도록 구현 된 특수 기능 이 있습니다. 이 경우 내 대안 솔루션입니다.
#define B_0000 0
#define B_0001 1
#define B_0010 2
#define B_0011 3
#define B_0100 4
#define B_0101 5
#define B_0110 6
#define B_0111 7
#define B_1000 8
#define B_1001 9
#define B_1010 a
#define B_1011 b
#define B_1100 c
#define B_1101 d
#define B_1110 e
#define B_1111 f
#define _B2H(bits) B_##bits
#define B2H(bits) _B2H(bits)
#define _HEX(n) 0x##n
#define HEX(n) _HEX(n)
#define _CCAT(a,b) a##b
#define CCAT(a,b) _CCAT(a,b)
#define BYTE(a,b) HEX( CCAT(B2H(a),B2H(b)) )
#define WORD(a,b,c,d) HEX( CCAT(CCAT(B2H(a),B2H(b)),CCAT(B2H(c),B2H(d))) )
#define DWORD(a,b,c,d,e,f,g,h) HEX( CCAT(CCAT(CCAT(B2H(a),B2H(b)),CCAT(B2H(c),B2H(d))),CCAT(CCAT(B2H(e),B2H(f)),CCAT(B2H(g),B2H(h)))) )
// Using example
char b = BYTE(0100,0001); // Equivalent to b = 65; or b = 'A'; or b = 0x41;
unsigned int w = WORD(1101,1111,0100,0011); // Equivalent to w = 57155; or w = 0xdf43;
unsigned long int dw = DWORD(1101,1111,0100,0011,1111,1101,0010,1000); //Equivalent to dw = 3745774888; or dw = 0xdf43fd28;
단점 (그다지 큰 것은 아닙니다) :
- 이진수는 4×4로 그룹화해야합니다.
- 이진 리터럴은 부호없는 정수 여야합니다.
장점 :
spending processor time
무의미한 작업이 아닌 전체 전 처리기 구동 (like "?.. :..", "<<", "+"
실행 가능한 프로그램에 대한 )이 (최종 응용 프로그램에서 수백 번 수행 될 수 있음);"mainly in C"
컴파일러와 C ++도 작동 합니다 (template+enum solution works only in C++ compilers
);- “문자 상수”값을 표현하기 위해 “길이”의 한계 만 있습니다.
"enum solution" (usually 255 = reach enum definition limit)
컴파일러에서 “리터럴 상수”한계를 다르게 해석하여 상수 값을 표현한 경우 컴파일러에서 더 큰 숫자를 허용하면 초기 경도 제한 (보통 8 비트 : 0-255)이 발생했을 것 입니다. - 일부 다른 솔루션은 길거나
several header files
(대부분의 경우 쉽게 읽고 이해할 수 없으며 프로젝트를 사용하는 것과 같이 불필요하게 혼란스럽고 확장되게합니다 )을 포함하여 많은 수의 상수 정의 (제 의견으로는 너무 많은 정의"BOOST_BINARY()"
)를 요구합니다. - 솔루션의 단순성 : 다른 경우에 대해 쉽게 읽고 이해하고 조절할 수 있습니다 (8×8 그룹화도 확장 가능).
답변
/* Helper macros */
#define HEX__(n) 0x##n##LU
#define B8__(x) ((x&0x0000000FLU)?1:0) \
+((x&0x000000F0LU)?2:0) \
+((x&0x00000F00LU)?4:0) \
+((x&0x0000F000LU)?8:0) \
+((x&0x000F0000LU)?16:0) \
+((x&0x00F00000LU)?32:0) \
+((x&0x0F000000LU)?64:0) \
+((x&0xF0000000LU)?128:0)
/* User macros */
#define B8(d) ((unsigned char)B8__(HEX__(d)))
#define B16(dmsb,dlsb) (((unsigned short)B8(dmsb)<<8) \
+ B8(dlsb))
#define B32(dmsb,db2,db3,dlsb) (((unsigned long)B8(dmsb)<<24) \
+ ((unsigned long)B8(db2)<<16) \
+ ((unsigned long)B8(db3)<<8) \
+ B8(dlsb))
#include <stdio.h>
int main(void)
{
// 261, evaluated at compile-time
unsigned const number = B16(00000001,00000101);
printf("%d \n", number);
return 0;
}
효과가있다! (모든 크레딧은 Tom Torfs에게 전달됩니다.)
답변
이미 대답했듯이 C 표준은 이진수를 직접 쓰는 방법이 없습니다. 그러나 컴파일러 확장이 있지만 분명히 C ++ 14에는0b
바이너리 접두사가 . (이 답변은 원래 2010 년에 게시되었습니다.)
널리 사용되는 해결 방법은 도우미 매크로 가 포함 된 헤더 파일 을 포함 시키는 것 입니다. 하나의 쉬운 옵션은 또한 모든 8 비트 패턴에 대한 매크로 정의를 포함하는 파일을 생성하는 것입니다.
#define B00000000 0
#define B00000001 1
#define B00000010 2
…
이로 인해 256 초만 발생하고 #define
8 비트 이진 상수보다 큰 경우 이러한 정의를 시프트 및 OR과 함께 가능하면 도우미 매크로와 함께 사용할 수 있습니다 (예 :BIN16(B00000001,B00001010)
. (32 비트는 물론 16 비트마다 개별 매크로를 갖는 것은 가치가 없습니다.)
물론 단점은이 구문은 모든 선행 0을 작성해야하지만, 이는 비트 플래그 및 하드웨어 레지스터의 내용 설정과 같은 용도로 더 명확해질 수 있다는 것입니다. 이 속성이없는 구문을 생성하는 함수와 유사한 매크로에 대해서는 bithacks.h
위의 링크를 참조하십시오 .