C 또는 C++로 바이너리 리터럴을 사용할 수 있습니까?
이진수로 작업해야 합니다.
글을 써보려고 했는데:
const x = 00010000;
하지만 그것은 작동하지 않았다.
라고 하는 것은 라고 하는 과 같은 할 수 을 알고 .00010000그런데 이진수 타입이 C++에 있는지 알고 싶습니다만, 없다면 다른 해결 방법이 있을까요?
GCC 를 사용하고 있는 경우는, 다음과 같이 GCC 확장(C++14 표준에 포함되어 있습니다)을 사용할 수 있습니다.
int x = 0b00010000;
이진 리터럴을 사용할 수 있습니다.C++14로 표준화되어 있습니다.예를들면,
int x = 0b11000;
GCC에서의 지원
GCC에서의 지원은 GCC 4.3에서 시작되었습니다(https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions),을 참조해 주세요(https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions),을 참조).GCC 4.9 이후 C++14 기능 또는 확장 기능(GCC 바이너리 리터럴과 C++14의 차이 참조).
Visual Studio 지원
Visual Studio의 지원은 Visual Studio 2015 Preview에서 시작되었습니다(https://www.visualstudio.com/news/vs2015-preview-vs#C++) 참조).
C++ 과엔지니어링의 사고방식은 이미 다른 답변에서도 잘 설명되고 있습니다.C, Keep-It-Simple-ffs라는 사고방식으로 이를 실현하기 위한 저의 시도는 다음과 같습니다.
unsigned char x = 0xF; // binary: 00001111
이 실이 도움이 될 것이다.
/* 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;
}
됐다! (모든 학점은 톰 토프에게 돌아간다.)
이미 답한 바와 같이 C 규격에는 바이너리 숫자를 직접 쓸 수 있는 방법이 없습니다. 확장기능이 에는 C++14가 되어 있는 것 .0b (이 2010년에
일반적인 회피책 중 하나는 도우미 매크로가 있는 헤더파일을 포함하는 것입니다.한 가지 쉬운 옵션은 모든 8비트 패턴에 대한 매크로 정의를 포함하는 파일을 생성하는 것입니다. 예를 들어 다음과 같습니다.
#define B00000000 0
#define B00000001 1
#define B00000010 2
…
256의 의 256만 남았습니다.#define 및 보다 큰 및 할 수 도우미 를 들면, s 「8」)와 할 수 있습니다.BIN16(B00000001,B00001010) 것도 매크로가 것은 할 수 (32비트에서는 16비트라고 합니다.)
물론 단점은 이 구문에서 선두에 있는 0을 모두 써야 한다는 것입니다.그러나 비트플래그나 하드웨어 레지스터의 콘텐츠 설정 등의 용도를 명확하게 할 수도 있습니다.이하지 않고 는 을 해 주세요.bithacks.h를 참조해 주세요.
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++0x 를 기다리는 동안 을 사용할 수 있습니다. : )BOOST_BINARYC 프로그램에서도 사용할 수 있는 한 템플릿 구현보다 유리합니다(100% 프리프로세서 구동).
반대로 하려면(즉, 이진 형식으로 숫자를 인쇄) 포터블 이외의 기능을 사용하거나 자신만의 기능을 구현할 수 있습니다.
유감스럽게도 STL 스트림에서는 base 2 포맷을 실행할 수 없습니다(는 base 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
또한 흥미로운 토론을 위해 허브 서터의 "장원 농장의 스트링 포메터"를 읽어보십시오.
다른 답변에 기반하지만, 이 답변은 바이너리 리터럴이 잘못된 프로그램을 거부합니다.선행 0은 옵션입니다.
template<bool> struct BinaryLiteralDigit;
template<> struct BinaryLiteralDigit<true> {
static bool const value = true;
};
template<unsigned long long int OCT, unsigned long long int HEX>
struct BinaryLiteral {
enum {
value = (BinaryLiteralDigit<(OCT%8 < 2)>::value && BinaryLiteralDigit<(HEX >= 0)>::value
? (OCT%8) + (BinaryLiteral<OCT/8, 0>::value << 1)
: -1)
};
};
template<>
struct BinaryLiteral<0, 0> {
enum {
value = 0
};
};
#define BINARY_LITERAL(n) BinaryLiteral<0##n##LU, 0x##n##LU>::value
예제:
#define B BINARY_LITERAL
#define COMPILE_ERRORS 0
int main (int argc, char ** argv) {
int _0s[] = { 0, B(0), B(00), B(000) };
int _1s[] = { 1, B(1), B(01), B(001) };
int _2s[] = { 2, B(10), B(010), B(0010) };
int _3s[] = { 3, B(11), B(011), B(0011) };
int _4s[] = { 4, B(100), B(0100), B(00100) };
int neg8s[] = { -8, -B(1000) };
#if COMPILE_ERRORS
int errors[] = { B(-1), B(2), B(9), B(1234567) };
#endif
return 0;
}
C++14부터는 바이너리 리터럴을 사용할 수 있습니다.이것이 언어의 일부입니다.
unsigned char a = 0b00110011;
C에는 순수 이진수에 대한 네이티브 표기법이 없습니다.여기서 가장 좋은 방법은 8진수(예:0777716진수(예:0xfff를 참조해 주세요.
일부 컴파일러(일반적으로 마이크로 컨트롤러용 컴파일러)에는 프리픽스 0b에 의한 리터럴 바이너리 번호를 인식하는 특수한 기능이 실장되어 있습니다.". " 대부분의 컴파일러(C/C++ 표준)에는 이러한 기능이 없습니다만, 그러한 경우 대체 솔루션은 다음과 같습니다.
#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로 그룹화해야 합니다.
- 이진 리터럴은 부호 없는 정수여야 합니다.
장점:
- 구동 「」가 아닙니다( 「」).
spending processor timelike "?.. :..", "<<", "+"실행 가능한 프로그램(최종 어플리케이션에서 수백 번 실행 가능)에 대한 정보 - 가 있다.
"mainly in C"도 마찬가지입니다.template+enum solution works only in C++ compilers - 그것은 "문자 상수" 값을 표현하기 위한 "길이"의 한계만을 가지고 있다.「」( 「8」): 「0~255)」의 하고, 한 값을 , 0~255이 있습니다.
"enum solution" (usually 255 = reach enum definition limit)이와는 달리 컴파일러의 "상수" 제한은 더 많은 수를 허용합니다. - 이나 롱을 한 상수 를
several header files쉽게 수 수 없으며, 확장합니다. , (예를 들어,)를 사용하는 경우입니다."BOOST_BINARY()" - 솔루션의 심플성: 읽기 쉽고, 이해하기 쉽고, 다른 케이스에서도 조정 가능(8개 그룹화도 가능)
인라인 어셈블리는 다음과 같이 사용할 수도 있습니다.
int i;
__asm {
mov eax, 00000000000000000000000000000000b
mov i, eax
}
std::cout << i;
좋아요, 다소 과잉 살상이긴 하지만 효과가 있어요
C++의 표준 라이브러리를 사용합니다.
#include <bitset>
경우 합니다.std::bitset:
std::bitset<8ul> x;
x = std::bitset<8>(10);
for (int i = x.size() - 1; i >= 0; i--) {
std::cout << x[i];
}
예에서는 , 즉 2진법 을 저장해 두었습니다.10x.
8ul 「」는 「」를 참조해당됩니다.7ul합니다.7비트 등을 의미합니다.
이 질문의 함수를 사용하면 C++에서 최대 22비트를 얻을 수 있습니다.적절히 편집된 링크의 코드는 다음과 같습니다.
template< unsigned long long N >
struct binary
{
enum { value = (N % 8) + 2 * binary< N / 8 > :: value } ;
};
template<>
struct binary< 0 >
{
enum { value = 0 } ;
};
이렇게 요.binary<0101011011>::value.
의 " 또는 . "10진수", "10진수", "16진수"는 8진수입니다.int(마지막 문자, 짧은 문자, 긴 문자)
상수를 할당할 때는 11011011로 할당할 수 없지만(16진수)은 사용할 수 있습니다.헥스는 정신적으로 번역하기 조금 더 쉽다.니블(4비트) 단위로 청크하고 [0-9a-f]의 문자로 변환합니다.
저는 @renato-chandlier의 좋은 답변을 다음과 같은 지원으로 확대했습니다.
_NIBBLE_(…)- "4" "1"_BYTE_(…)– 8 트, 、 2 블 –_SLAB_(…): "12" "3"_WORD_(…)- "16" "4"_QUINTIBBLE_(…)- "20" "5"_DSLAB_(…)- "24" "6"_SEPTIBBLE_(…)- "28", "7"_DWORD_(…): 32비트, 8비트
나는 사실 "quintible"과 "septible"이라는 용어에 대해 잘 모르겠다.다른 대안을 아는 사람이 있으면 알려주세요.
다음은 매크로를 다시 쓴 것입니다.
#define __CAT__(A, B) A##B
#define _CAT_(A, B) __CAT__(A, B)
#define __HEX_0000 0
#define __HEX_0001 1
#define __HEX_0010 2
#define __HEX_0011 3
#define __HEX_0100 4
#define __HEX_0101 5
#define __HEX_0110 6
#define __HEX_0111 7
#define __HEX_1000 8
#define __HEX_1001 9
#define __HEX_1010 a
#define __HEX_1011 b
#define __HEX_1100 c
#define __HEX_1101 d
#define __HEX_1110 e
#define __HEX_1111 f
#define _NIBBLE_(N1) _CAT_(0x, _CAT_(__HEX_, N1))
#define _BYTE_(N1, N2) _CAT_(_NIBBLE_(N1), _CAT_(__HEX_, N2))
#define _SLAB_(N1, N2, N3) _CAT_(_BYTE_(N1, N2), _CAT_(__HEX_, N3))
#define _WORD_(N1, N2, N3, N4) _CAT_(_SLAB_(N1, N2, N3), _CAT_(__HEX_, N4))
#define _QUINTIBBLE_(N1, N2, N3, N4, N5) _CAT_(_WORD_(N1, N2, N3, N4), _CAT_(__HEX_, N5))
#define _DSLAB_(N1, N2, N3, N4, N5, N6) _CAT_(_QUINTIBBLE_(N1, N2, N3, N4, N5), _CAT_(__HEX_, N6))
#define _SEPTIBBLE_(N1, N2, N3, N4, N5, N6, N7) _CAT_(_DSLAB_(N1, N2, N3, N4, N5, N6), _CAT_(__HEX_, N7))
#define _DWORD_(N1, N2, N3, N4, N5, N6, N7, N8) _CAT_(_SEPTIBBLE_(N1, N2, N3, N4, N5, N6, N7), _CAT_(__HEX_, N8))
Renato의 예는 다음과 같습니다.
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; */
C는 C++라는 이름의 표준 합니다.std::bitset츠요시
해 볼 수 있어요.bool:
bool i[8] = {0,0,1,1,0,1,0,1}
사용방법: 이진(00010001);
int BINARY(int a){ int b = 0;
for (int i = 0;i < 8;i++){
b += a % 10 << i;
a = a / 10;
}
return b;
}
할 수 입니다.charoperators.type)을할 수 . 단, 비트 연산자를 사용하여 비트로 작업할 수 있습니다.
정수 리터럴의 경우 10진수(기본값 10), 8진수(기본값 8) 또는 16진수(기본값 16) 숫자만 사용할 수 있습니다.C 또는 C++에는 바이너리(베이스 2) 리터럴이 없습니다.
에는 8이 붙는다.0 16 에는 「16」이 붙습니다.0x접두사가 . 열 번
C++0x에서는 사용자가 정의한 리터럴을 통해 원하는 작업을 수행할 수 있습니다.
비트셋을 사용할 수 있습니다.
bitset<8> b(string("00010000"));
int i = (int)(bs.to_ulong());
cout<<i;
Boost 라이브러리를 추가하지 않은 기능을 다음에 나타냅니다.
: "사용방법" :BOOST_BINARY(00010001);
int BOOST_BINARY(int a){
int b = 0;
for (int i = 0;i < 8;i++){
b += a % 10 << i;
a = a / 10;
}
return b;
}
언급URL : https://stackoverflow.com/questions/2611764/can-i-use-a-binary-literal-in-c-or-c
'programing' 카테고리의 다른 글
| 어떻게 평역에 지속적인 자바에서 값으로 공급됩니다. (0) | 2022.07.25 |
|---|---|
| IntelliJ IDEA 기본 JDK 변경 방법 (0) | 2022.07.25 |
| 다차원 어레이는 메모리에서 어떻게 포맷됩니까? (0) | 2022.07.25 |
| nuxt의 가져오기 함수 내에서 스토어 액션을 디스패치하려면 어떻게 해야 합니다. (0) | 2022.07.25 |
| MinGW를 사용하여 makefile을 컴파일하려면 어떻게 해야 하나요? (0) | 2022.07.25 |