16 진수 또는 8 진수로 printf를 사용하여 인쇄 할 수 있습니다. 이진 또는 임의의 기준으로 인쇄 할 형식 태그가 있습니까?
gcc를 실행 중입니다.
printf("%d %x %o\n", 10, 10, 10); //prints "10 A 12\n"
print("%b\n", 10); // prints "%b\n"
16 진수 또는 8 진수로 printf를 사용하여 인쇄 할 수 있습니다. 이진 또는 임의의 기준으로 인쇄 할 형식 태그가 있습니까?
gcc를 실행 중입니다.
printf("%d %x %o\n", 10, 10, 10); //prints "10 A 12\n"
print("%b\n", 10); // prints "%b\n"
답변:
해 키지 만 나를 위해 작동합니다.
#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
#define BYTE_TO_BINARY(byte) \
(byte & 0x80 ? '1' : '0'), \
(byte & 0x40 ? '1' : '0'), \
(byte & 0x20 ? '1' : '0'), \
(byte & 0x10 ? '1' : '0'), \
(byte & 0x08 ? '1' : '0'), \
(byte & 0x04 ? '1' : '0'), \
(byte & 0x02 ? '1' : '0'), \
(byte & 0x01 ? '1' : '0')
printf("Leading text "BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(byte));
멀티 바이트 유형의 경우
printf("m: "BYTE_TO_BINARY_PATTERN" "BYTE_TO_BINARY_PATTERN"\n",
BYTE_TO_BINARY(m>>8), BYTE_TO_BINARY(m));
불행히도 모든 여분의 따옴표가 필요합니다. 이 접근법은 매크로의 효율성 위험이 BYTE_TO_BINARY
있지만 ( 함수를의 인수로 전달하지 마십시오 ) 여기 다른 제안에서 메모리 문제와 strcat의 여러 호출을 피하십시오.
printf
와 함께있는 사람 static
버퍼 수 없습니다입니다.
int
시스템에서 32 비트 라고 가정하면 단일 32 비트 값을 인쇄하려면 32 * 4 바이트 값을위한 공간이 필요합니다. 총 128 바이트 스택 크기에 따라 문제가 될 수도 있고 아닐 수도 있습니다.
모든 데이터 유형에 대한 이진 인쇄
//assumes little endian
void printBits(size_t const size, void const * const ptr)
{
unsigned char *b = (unsigned char*) ptr;
unsigned char byte;
int i, j;
for (i=size-1;i>=0;i--)
{
for (j=7;j>=0;j--)
{
byte = (b[i] >> j) & 1;
printf("%u", byte);
}
}
puts("");
}
테스트
int main(int argv, char* argc[])
{
int i = 23;
uint ui = UINT_MAX;
float f = 23.45f;
printBits(sizeof(i), &i);
printBits(sizeof(ui), &ui);
printBits(sizeof(f), &f);
return 0;
}
size_t i; for (i=size; i-- > 0; )
피하기 위해 size_t
대의 int
잘못 일치.
ptr
(외부 루프). 그런 다음 각 비트에 대해 현재 바이트 (내부 루프)에 대해 현재 비트 ( 1 << j
)로 바이트를 마스크하십시오 . 오른쪽으로 이동하면 0 ( 0000 0000b
) 또는 1 ( 0000 0001b
)을 포함하는 바이트가 됩니다. format을 사용하여 결과 바이트 printf를 인쇄하십시오 %u
. HTH.
>
과 >=
서명되지 않은 유형입니다. 0
부호없는 엣지 케이스이며 덜 일반적으로 부호있는 수학과 달리 일반적으로 발생합니다 INT_MAX/INT_MIN
.
다음은 원하는 것을 수행하는 기술을 보여주는 빠른 해킹입니다.
#include <stdio.h> /* printf */
#include <string.h> /* strcat */
#include <stdlib.h> /* strtol */
const char *byte_to_binary
(
int x
)
{
static char b[9];
b[0] = '\0';
int z;
for (z = 128; z > 0; z >>= 1)
{
strcat(b, ((x & z) == z) ? "1" : "0");
}
return b;
}
int main
(
void
)
{
{
/* binary string to int */
char *tmp;
char *b = "0101";
printf("%d\n", strtol(b, &tmp, 2));
}
{
/* byte to binary string */
printf("%s\n", byte_to_binary(5));
}
return 0;
}
strcat
은 루프의 각 패스에서 단일 문자를 문자열에 추가하는 비효율적 인 방법입니다. 대신 a를 추가 char *p = b;
하고 내부 루프를로 바꿉니다 *p++ = (x & z) ? '1' : '0'
. z
256 (2 ^ 8) 대신 128 (2 ^ 7)부터 시작해야합니다. (쓰레드 안전을 위해) 사용할 버퍼에 포인터를 가져와 업데이트를 고려하십시오 inet_ntoa()
.
strcat()
! strcat
과제에 대한 역 참조 된 포인터를 사후 증가시키는 것보다 이해하기 쉽다는 데 동의 하지만 초보자도 표준 라이브러리를 올바르게 사용하는 방법을 알아야합니다. 할당을 위해 인덱스 배열을 사용하는 것이 좋은 데모 일 것입니다 (실제로 b
함수를 호출 할 때마다 모두 0으로 재설정되지 않기 때문에 실제로 작동 합니다).
printf("%s + %s = %s", byte_to_binary(3), byte_to_binary(4), byte_to_binary(3+4))
.
glibc에는 바이너리 변환 지정자가 없습니다.
glibc의 printf () 함수 계열에 사용자 정의 변환 유형을 추가 할 수 있습니다. register_printf_function 참조 을 참조하십시오. 응용 프로그램 코드를 단순화하여 사용할 수 있도록 사용자 지정 % b 변환을 직접 사용할 수 있습니다.
다음은 glibc에서 사용자 정의 printf 형식을 구현하는 방법 의 예 입니다.
warning: 'register_printf_function' is deprecated [-Wdeprecated-declarations]
그래도 동일한 기능을 수행하는 새로운 기능이 있습니다 register_printf_specifier()
. 새로운 사용의 예는 여기에서 찾을 수 있습니다 : codereview.stackexchange.com/q/219994/200418을
작은 테이블을 사용하여 속도를 향상시킬 수 있습니다 1 . 예를 들어 바이트를 반전시키는 것과 같은 내장 기술에서 비슷한 기술이 유용합니다.
const char *bit_rep[16] = {
[ 0] = "0000", [ 1] = "0001", [ 2] = "0010", [ 3] = "0011",
[ 4] = "0100", [ 5] = "0101", [ 6] = "0110", [ 7] = "0111",
[ 8] = "1000", [ 9] = "1001", [10] = "1010", [11] = "1011",
[12] = "1100", [13] = "1101", [14] = "1110", [15] = "1111",
};
void print_byte(uint8_t byte)
{
printf("%s%s", bit_rep[byte >> 4], bit_rep[byte & 0x0F]);
}
1 주로 옵티마이 저가 그리 공격적이지 않고 속도 차이가 보이는 임베디드 응용 프로그램을 말합니다.
최하위 비트를 인쇄하여 오른쪽으로 옮기십시오. 정수가 0이 될 때까지이 작업을 수행하면 선행 0없이 이진 표현이 인쇄되지만 역순으로 인쇄됩니다. 재귀를 사용하면 순서를 쉽게 수정할 수 있습니다.
#include <stdio.h>
void print_binary(int number)
{
if (number) {
print_binary(number >> 1);
putc((number & 1) ? '1' : '0', stdout);
}
}
나에게 이것은 문제에 대한 가장 깨끗한 해결책 중 하나입니다. 0b
접두사와 후행 줄 바꿈 문자 를 좋아한다면 함수를 래핑하는 것이 좋습니다.
putc('0'+(number&1), stdout);
@William 와이트의 답변에 따라,이 제공하는 매크로이다 int8
, 16
, 32
및 64
재사용 버전 INT8
피하기 반복에 매크로를.
/* --- PRINTF_BYTE_TO_BINARY macro's --- */
#define PRINTF_BINARY_PATTERN_INT8 "%c%c%c%c%c%c%c%c"
#define PRINTF_BYTE_TO_BINARY_INT8(i) \
(((i) & 0x80ll) ? '1' : '0'), \
(((i) & 0x40ll) ? '1' : '0'), \
(((i) & 0x20ll) ? '1' : '0'), \
(((i) & 0x10ll) ? '1' : '0'), \
(((i) & 0x08ll) ? '1' : '0'), \
(((i) & 0x04ll) ? '1' : '0'), \
(((i) & 0x02ll) ? '1' : '0'), \
(((i) & 0x01ll) ? '1' : '0')
#define PRINTF_BINARY_PATTERN_INT16 \
PRINTF_BINARY_PATTERN_INT8 PRINTF_BINARY_PATTERN_INT8
#define PRINTF_BYTE_TO_BINARY_INT16(i) \
PRINTF_BYTE_TO_BINARY_INT8((i) >> 8), PRINTF_BYTE_TO_BINARY_INT8(i)
#define PRINTF_BINARY_PATTERN_INT32 \
PRINTF_BINARY_PATTERN_INT16 PRINTF_BINARY_PATTERN_INT16
#define PRINTF_BYTE_TO_BINARY_INT32(i) \
PRINTF_BYTE_TO_BINARY_INT16((i) >> 16), PRINTF_BYTE_TO_BINARY_INT16(i)
#define PRINTF_BINARY_PATTERN_INT64 \
PRINTF_BINARY_PATTERN_INT32 PRINTF_BINARY_PATTERN_INT32
#define PRINTF_BYTE_TO_BINARY_INT64(i) \
PRINTF_BYTE_TO_BINARY_INT32((i) >> 32), PRINTF_BYTE_TO_BINARY_INT32(i)
/* --- end macros --- */
#include <stdio.h>
int main() {
long long int flag = 1648646756487983144ll;
printf("My Flag "
PRINTF_BINARY_PATTERN_INT64 "\n",
PRINTF_BYTE_TO_BINARY_INT64(flag));
return 0;
}
이 결과는 다음과 같습니다.
My Flag 0001011011100001001010110111110101111000100100001111000000101000
가독성을 위해 다음과 같은 구분 기호를 추가 할 수 있습니다.
My Flag 00010110,11100001,00101011,01111101,01111000,10010000,11110000,00101000
PRINTF_BYTE_TO_BINARY_INT#
선택적으로 사용할 그룹화 된 버전의 정의를 추가합니다 .
다음은 재진입 문제 나 인수의 크기 / 유형에 대한 제한이없는 함수 버전입니다.
#define FMT_BUF_SIZE (CHAR_BIT*sizeof(uintmax_t)+1)
char *binary_fmt(uintmax_t x, char buf[static FMT_BUF_SIZE])
{
char *s = buf + FMT_BUF_SIZE;
*--s = 0;
if (!x) *--s = '0';
for(; x; x/=2) *--s = '0' + x%2;
return s;
}
이 코드는 2를 원하는베이스로 바꾸면 2에서 10 사이의베이스에 대해서도 잘 작동합니다. 사용법은 :
char tmp[FMT_BUF_SIZE];
printf("%s\n", binary_fmt(x, tmp));
x
완전한 표현은 어디에 있습니까 ?
char *a = binary_fmt(x), *b = binary_fmt(y);
이 예상대로 작동하지 않음을 알고 있어야합니다 . 호출자가 버퍼를 전달하도록하면 스토리지 요구 사항이 명시됩니다. 호출자가 실제로 원하는 경우 정적 버퍼를 자유롭게 사용할 수 있으며 동일한 버퍼의 재사용이 명시 적입니다. 또한 최신 PIC ABI에서 정적 버퍼는 일반적으로 스택의 버퍼보다 액세스하는 데 더 많은 코드가 필요합니다.
const char* byte_to_binary( int x )
{
static char b[sizeof(int)*8+1] = {0};
int y;
long long z;
for (z=1LL<<sizeof(int)*8-1,y=0; z>0; z>>=1,y++)
{
b[y] = ( ((x & z) == z) ? '1' : '0');
}
b[y] = 0;
return b;
}
'1'
와 '0'
대신 49
과 48
당신의 삼항에. 또한 b
마지막 문자가 널 종료 자로 남아있을 수 있도록 9 자 길이 여야합니다.
static char b[9] = {0}
2. 루프 밖으로 선언을 이동 int z,y;
하십시오 . 3. 최종 0을 추가하십시오 b[y] = 0
. 이런 식으로 재 초기화가 필요하지 않습니다.
8
을로 교체해야합니다 CHAR_BIT
.
빠르고 쉬운 솔루션 :
void printbits(my_integer_type x)
{
for(int i=sizeof(x)<<3; i; i--)
putchar('0'+((x>>(i-1))&1));
}
모든 크기 유형과 부호있는 및 부호없는 정수에 사용할 수 있습니다. '& 1'은 시프트가 부호 확장을 할 수 있으므로 부호있는 정수를 처리하는 데 필요합니다.
이를 수행하는 방법에는 여러 가지가 있습니다. 부호있는 또는 부호없는 32 비트 유형 (부호가있는 경우 음수를 넣지 않고 실제 비트 만 인쇄)에서 캐리지 리턴이없는 32 비트 또는 n 비트를 인쇄하는 매우 간단한 방법입니다. 비트 시프트 전에 i가 감소합니다.
#define printbits_n(x,n) for (int i=n;i;i--,putchar('0'|(x>>i)&1))
#define printbits_32(x) printbits_n(x,32)
나중에 저장하거나 인쇄 할 비트가 포함 된 문자열을 반환하는 것은 어떻습니까? 메모리를 할당하고 반환 할 수 있으며 사용자가 메모리를 해제해야합니다. 그렇지 않으면 정적 문자열을 반환하지만 다시 호출하거나 다른 스레드에 의해 클러버가 발생합니다. 표시된 두 가지 방법 :
char *int_to_bitstring_alloc(int x, int count)
{
count = count<1 ? sizeof(x)*8 : count;
char *pstr = malloc(count+1);
for(int i = 0; i<count; i++)
pstr[i] = '0' | ((x>>(count-1-i))&1);
pstr[count]=0;
return pstr;
}
#define BITSIZEOF(x) (sizeof(x)*8)
char *int_to_bitstring_static(int x, int count)
{
static char bitbuf[BITSIZEOF(x)+1];
count = (count<1 || count>BITSIZEOF(x)) ? BITSIZEOF(x) : count;
for(int i = 0; i<count; i++)
bitbuf[i] = '0' | ((x>>(count-1-i))&1);
bitbuf[count]=0;
return bitbuf;
}
전화 :
// memory allocated string returned which needs to be freed
char *pstr = int_to_bitstring_alloc(0x97e50ae6, 17);
printf("bits = 0b%s\n", pstr);
free(pstr);
// no free needed but you need to copy the string to save it somewhere else
char *pstr2 = int_to_bitstring_static(0x97e50ae6, 17);
printf("bits = 0b%s\n", pstr2);
이전에 게시 된 답변 중 어느 것도 내가 찾던 것이 아니므로 하나를 썼습니다. 와 함께 % B를 사용하는 것은 매우 간단합니다 printf
!
/*
* File: main.c
* Author: Techplex.Engineer
*
* Created on February 14, 2012, 9:16 PM
*/
#include <stdio.h>
#include <stdlib.h>
#include <printf.h>
#include <math.h>
#include <string.h>
static int printf_arginfo_M(const struct printf_info *info, size_t n, int *argtypes) {
/* "%M" always takes one argument, a pointer to uint8_t[6]. */
if (n > 0) {
argtypes[0] = PA_POINTER;
}
return 1;
} /* printf_arginfo_M */
static int printf_output_M(FILE *stream, const struct printf_info *info, const void *const *args) {
int value = 0;
int len;
value = *(int **) (args[0]);
//Beginning of my code ------------------------------------------------------------
char buffer [50] = ""; //Is this bad?
char buffer2 [50] = ""; //Is this bad?
int bits = info->width;
if (bits <= 0)
bits = 8; // Default to 8 bits
int mask = pow(2, bits - 1);
while (mask > 0) {
sprintf(buffer, "%s", (((value & mask) > 0) ? "1" : "0"));
strcat(buffer2, buffer);
mask >>= 1;
}
strcat(buffer2, "\n");
// End of my code --------------------------------------------------------------
len = fprintf(stream, "%s", buffer2);
return len;
} /* printf_output_M */
int main(int argc, char** argv) {
register_printf_specifier('B', printf_output_M, printf_arginfo_M);
printf("%4B\n", 65);
return (EXIT_SUCCESS);
}
char* buffer = (char*) malloc(sizeof(char) * 50);
char *buffer = malloc(sizeof(*buffer) * 50);
표준이 아니지만 일부 런타임은 "% b"을 (를) 지원합니다.
흥미로운 토론을 보려면 여기를 참조하십시오.
http://bytes.com/forum/thread591027.html
HTH
이 코드는 최대 64 비트의 요구를 처리해야합니다. pBin & pBinFill이라는 2 개의 함수를 만들었습니다. 둘 다 동일한 작업을 수행하지만 pBinFill은 선행 공백을 fillChar로 채 웁니다. 테스트 기능은 일부 테스트 데이터를 생성 한 다음이 기능을 사용하여 인쇄합니다.
char* pBinFill(long int x,char *so, char fillChar); // version with fill
char* pBin(long int x, char *so); // version without fill
#define kDisplayWidth 64
char* pBin(long int x,char *so)
{
char s[kDisplayWidth+1];
int i=kDisplayWidth;
s[i--]=0x00; // terminate string
do
{ // fill in array from right to left
s[i--]=(x & 1) ? '1':'0'; // determine bit
x>>=1; // shift right 1 bit
} while( x > 0);
i++; // point to last valid character
sprintf(so,"%s",s+i); // stick it in the temp string string
return so;
}
char* pBinFill(long int x,char *so, char fillChar)
{ // fill in array from right to left
char s[kDisplayWidth+1];
int i=kDisplayWidth;
s[i--]=0x00; // terminate string
do
{ // fill in array from right to left
s[i--]=(x & 1) ? '1':'0';
x>>=1; // shift right 1 bit
} while( x > 0);
while(i>=0) s[i--]=fillChar; // fill with fillChar
sprintf(so,"%s",s);
return so;
}
void test()
{
char so[kDisplayWidth+1]; // working buffer for pBin
long int val=1;
do
{
printf("%ld =\t\t%#lx =\t\t0b%s\n",val,val,pBinFill(val,so,'0'));
val*=11; // generate test data
} while (val < 100000000);
}
Output:
00000001 = 0x000001 = 0b00000000000000000000000000000001
00000011 = 0x00000b = 0b00000000000000000000000000001011
00000121 = 0x000079 = 0b00000000000000000000000001111001
00001331 = 0x000533 = 0b00000000000000000000010100110011
00014641 = 0x003931 = 0b00000000000000000011100100110001
00161051 = 0x02751b = 0b00000000000000100111010100011011
01771561 = 0x1b0829 = 0b00000000000110110000100000101001
19487171 = 0x12959c3 = 0b00000001001010010101100111000011
width
대신 일반적인 이름을 사용하기 위해 log4cxx에게 알려 주어야 합니다!
이진 형식으로 인쇄 할 printf 변환기가 있습니까?
이 printf()
제품군은 표준 지정자를 사용하여 8, 10 및 16 기반으로 만 인쇄 할 수 있습니다. 코드의 특정 요구에 따라 숫자를 문자열로 변환하는 함수를 만드는 것이 좋습니다.
베이스에 인쇄하려면 [2-36]
지금까지 다른 모든 답변에는 이러한 제한 중 하나 이상이 있습니다.
리턴 버퍼에 정적 메모리를 사용하십시오. 이것은 함수가에 대한 인수로 사용될 수있는 횟수를 제한합니다 printf()
.
포인터를 비우려면 호출 코드가 필요한 메모리를 할당하십시오.
적절한 버퍼를 명시 적으로 제공하려면 호출 코드가 필요합니다.
printf()
직접 전화하십시오 . 이것은을위한 새로운 기능 의무화 fprintf()
, sprintf()
, vsprintf()
, 등
감소 된 정수 범위를 사용하십시오.
다음은 위의 제한이 없습니다 . C99 이상이 필요합니다 "%s"
. 이것은 사용하는 화합물 리터럴 버퍼 공간을 제공 할 수있다. 의 여러 통화에는 문제가 없습니다 printf()
.
#include <assert.h>
#include <limits.h>
#define TO_BASE_N (sizeof(unsigned)*CHAR_BIT + 1)
// v. compound literal .v
#define TO_BASE(x, b) my_to_base((char [TO_BASE_N]){""}, (x), (b))
// Tailor the details of the conversion function as needed
// This one does not display unneeded leading zeros
// Use return value, not `buf`
char *my_to_base(char *buf, unsigned i, int base) {
assert(base >= 2 && base <= 36);
char *s = &buf[TO_BASE_N - 1];
*s = '\0';
do {
s--;
*s = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i % base];
i /= base;
} while (i);
// Could employ memmove here to move the used buffer to the beginning
return s;
}
#include <stdio.h>
int main(void) {
int ip1 = 0x01020304;
int ip2 = 0x05060708;
printf("%s %s\n", TO_BASE(ip1, 16), TO_BASE(ip2, 16));
printf("%s %s\n", TO_BASE(ip1, 2), TO_BASE(ip2, 2));
puts(TO_BASE(ip1, 8));
puts(TO_BASE(ip1, 36));
return 0;
}
산출
1020304 5060708
1000000100000001100000100 101000001100000011100001000
100401404
A2F44
다음과 같은 재귀 함수가 유용 할 수 있습니다.
void bin(int n)
{
/* Step 1 */
if (n > 1)
bin(n/2);
/* Step 2 */
printf("%d", n % 2);
}
크기와 C ++에 대한 최고의 솔루션을 최적화 하고이 솔루션에 도달했습니다.
inline std::string format_binary(unsigned int x)
{
static char b[33];
b[32] = '\0';
for (int z = 0; z < 32; z++) {
b[31-z] = ((x>>z) & 0x1) ? '1' : '0';
}
return b;
}
std::string
제거 할 수도 있습니다 static
. 가장 간단한 방법은 static
한정자를 삭제 b
하고 함수에 로컬로 만드는 것 입니다.
((x>>z) & 0x01) + '0'
충분하다.
이 접근법은 다음과 같은 속성을 갖습니다.
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define for_endian(size) for (int i = 0; i < size; ++i)
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define for_endian(size) for (int i = size - 1; i >= 0; --i)
#else
#error "Endianness not detected"
#endif
#define printb(value) \
({ \
typeof(value) _v = value; \
__printb((typeof(_v) *) &_v, sizeof(_v)); \
})
void __printb(void *value, size_t size)
{
uint8_t byte;
size_t blen = sizeof(byte) * 8;
uint8_t bits[blen + 1];
bits[blen] = '\0';
for_endian(size) {
byte = ((uint8_t *) value)[i];
memset(bits, '0', blen);
for (int j = 0; byte && j < blen; ++j) {
if (byte & 0x80)
bits[j] = '1';
byte <<= 1;
}
printf("%s ", bits);
}
printf("\n");
}
int main(void)
{
uint8_t c1 = 0xff, c2 = 0x44;
uint8_t c3 = c1 + c2;
printb(c1);
printb((char) 0xff);
printb((short) 0xff);
printb(0xff);
printb(c2);
printb(0x44);
printb(0x4411ff01);
printb((uint16_t) c3);
printf("\n");
return 0;
}
$ ./printb
11111111
11111111
00000000 11111111
00000000 00000000 00000000 11111111
01000100
00000000 00000000 00000000 01000100
01000100 00010001 11111111 00000001
00000000 01000011
내가 사용한 또 다른 접근 방식 ( bitprint.h을 (비트 문자열로) 모든 바이트있는 테이블을 작성하고 입력 / 인덱스 바이트에 기반을 인쇄). 살펴볼 가치가 있습니다.
void
print_binary(unsigned int n)
{
unsigned int mask = 0;
/* this grotesque hack creates a bit pattern 1000... */
/* regardless of the size of an unsigned int */
mask = ~mask ^ (~mask >> 1);
for(; mask != 0; mask >>= 1) {
putchar((n & mask) ? '1' : '0');
}
}
paniq의 코드가 마음에 들었습니다. 정적 버퍼는 좋은 생각입니다. 그러나 단일 printf ()에서 여러 이진 형식을 원할 경우 항상 동일한 포인터를 반환하고 배열을 덮어 쓰므로 실패합니다.
다음은 스플릿 버퍼에서 포인터를 회전시키는 C 스타일 드롭 인입니다.
char *
format_binary(unsigned int x)
{
#define MAXLEN 8 // width of output format
#define MAXCNT 4 // count per printf statement
static char fmtbuf[(MAXLEN+1)*MAXCNT];
static int count = 0;
char *b;
count = count % MAXCNT + 1;
b = &fmtbuf[(MAXLEN+1)*count];
b[MAXLEN] = '\0';
for (int z = 0; z < MAXLEN; z++) { b[MAXLEN-1-z] = ((x>>z) & 0x1) ? '1' : '0'; }
return b;
}
count
도달 MAXCNT - 1
,의 다음 증분은 count
그것을 만들 것입니다 MAXCNT
배열의 경계 밖으로 액세스의 원인이되는 대신 제로의. 당신은해야합니다 count = (count + 1) % MAXCNT
.
MAXCNT + 1
함수에 대한 호출을 사용하는 개발자에게는 놀라운 일이 될 것 printf
입니다. 일반적으로 둘 이상의 옵션을 제공하려면 무한대로 만드십시오. 4와 같은 숫자는 문제를 일으킬 수 있습니다.
표준 라이브러리를 사용하여 모든 정수 유형 을 이진 문자열 표현으로 변환하는 하나의 명령문 일반 변환 :
#include <bitset>
MyIntegralType num = 10;
print("%s\n",
std::bitset<sizeof(num) * 8>(num).to_string().insert(0, "0b").c_str()
); // prints "0b1010\n"
아니면 그냥 : std::cout << std::bitset<sizeof(num) * 8>(num);
그의 대답에 @ ideasman42의 제안을 바탕으로,이 제공하는 매크로이다 int8
, 16
, 32
및 64
재사용 버전 INT8
피하기 반복에 매크로를.
/* --- PRINTF_BYTE_TO_BINARY macro's --- */
#define PRINTF_BINARY_SEPARATOR
#define PRINTF_BINARY_PATTERN_INT8 "%c%c%c%c%c%c%c%c"
#define PRINTF_BYTE_TO_BINARY_INT8(i) \
(((i) & 0x80ll) ? '1' : '0'), \
(((i) & 0x40ll) ? '1' : '0'), \
(((i) & 0x20ll) ? '1' : '0'), \
(((i) & 0x10ll) ? '1' : '0'), \
(((i) & 0x08ll) ? '1' : '0'), \
(((i) & 0x04ll) ? '1' : '0'), \
(((i) & 0x02ll) ? '1' : '0'), \
(((i) & 0x01ll) ? '1' : '0')
#define PRINTF_BINARY_PATTERN_INT16 \
PRINTF_BINARY_PATTERN_INT8 PRINTF_BINARY_SEPARATOR PRINTF_BINARY_PATTERN_INT8
#define PRINTF_BYTE_TO_BINARY_INT16(i) \
PRINTF_BYTE_TO_BINARY_INT8((i) >> 8), PRINTF_BYTE_TO_BINARY_INT8(i)
#define PRINTF_BINARY_PATTERN_INT32 \
PRINTF_BINARY_PATTERN_INT16 PRINTF_BINARY_SEPARATOR PRINTF_BINARY_PATTERN_INT16
#define PRINTF_BYTE_TO_BINARY_INT32(i) \
PRINTF_BYTE_TO_BINARY_INT16((i) >> 16), PRINTF_BYTE_TO_BINARY_INT16(i)
#define PRINTF_BINARY_PATTERN_INT64 \
PRINTF_BINARY_PATTERN_INT32 PRINTF_BINARY_SEPARATOR PRINTF_BINARY_PATTERN_INT32
#define PRINTF_BYTE_TO_BINARY_INT64(i) \
PRINTF_BYTE_TO_BINARY_INT32((i) >> 32), PRINTF_BYTE_TO_BINARY_INT32(i)
/* --- end macros --- */
#include <stdio.h>
int main() {
long long int flag = 1648646756487983144ll;
printf("My Flag "
PRINTF_BINARY_PATTERN_INT64 "\n",
PRINTF_BYTE_TO_BINARY_INT64(flag));
return 0;
}
이 결과는 다음과 같습니다.
My Flag 0001011011100001001010110111110101111000100100001111000000101000
가독성을 위해 당신은 변경할 수 있습니다 #define PRINTF_BINARY_SEPARATOR
에#define PRINTF_BINARY_SEPARATOR ","
나#define PRINTF_BINARY_SEPARATOR " "
출력됩니다 :
My Flag 00010110,11100001,00101011,01111101,01111000,10010000,11110000,00101000
또는
My Flag 00010110 11100001 00101011 01111101 01111000 10010000 11110000 00101000
사용하다:
char buffer [33];
itoa(value, buffer, 2);
printf("\nbinary: %s\n", buffer);
더 자세한 내용은 printf를 통해 이진수를 인쇄하는 방법을.
void print_ulong_bin(const unsigned long * const var, int bits) {
int i;
#if defined(__LP64__) || defined(_LP64)
if( (bits > 64) || (bits <= 0) )
#else
if( (bits > 32) || (bits <= 0) )
#endif
return;
for(i = 0; i < bits; i++) {
printf("%lu", (*var >> (bits - 1 - i)) & 0x01);
}
}
작동해야합니다-테스트되지 않았습니다.
/* Convert an int to it's binary representation */
char *int2bin(int num, int pad)
{
char *str = malloc(sizeof(char) * (pad+1));
if (str) {
str[pad]='\0';
while (--pad>=0) {
str[pad] = num & 1 ? '1' : '0';
num >>= 1;
}
} else {
return "";
}
return str;
}
/* example usage */
printf("The number 5 in binary is %s", int2bin(5, 4));
/* "The number 5 in binary is 0101" */
다음은 메모리 레이아웃을 보여줍니다.
#include <limits>
#include <iostream>
#include <string>
using namespace std;
template<class T> string binary_text(T dec, string byte_separator = " ") {
char* pch = (char*)&dec;
string res;
for (int i = 0; i < sizeof(T); i++) {
for (int j = 1; j < 8; j++) {
res.append(pch[i] & 1 ? "1" : "0");
pch[i] /= 2;
}
res.append(byte_separator);
}
return res;
}
int main() {
cout << binary_text(5) << endl;
cout << binary_text(.1) << endl;
return 0;
}
다음은 템플릿을 사용하여 32 및 64 비트 정수를 인쇄 할 수 있는 paniq 솔루션 의 작은 변형입니다 .
template<class T>
inline std::string format_binary(T x)
{
char b[sizeof(T)*8+1] = {0};
for (size_t z = 0; z < sizeof(T)*8; z++)
b[sizeof(T)*8-1-z] = ((x>>z) & 0x1) ? '1' : '0';
return std::string(b);
}
다음과 같이 사용할 수 있습니다.
unsigned int value32 = 0x1e127ad;
printf( " 0x%x: %s\n", value32, format_binary(value32).c_str() );
unsigned long long value64 = 0x2e0b04ce0;
printf( "0x%llx: %s\n", value64, format_binary(value64).c_str() );
결과는 다음과 같습니다.
0x1e127ad: 00000001111000010010011110101101
0x2e0b04ce0: 0000000000000000000000000000001011100000101100000100110011100000