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
)になります。結果のバイトprintfをformatで出力します%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()
。新しい使用法の例は次の場所に
小さなテーブルを使用して速度を向上させることができます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私は主に、オプティマイザがそれほど積極的ではなく、速度の違いが見える組み込みアプリケーションについて言及しています。
最下位ビットを出力し、右側にシフトアウトします。整数がゼロになるまでこれを行うと、先行ゼロなしで逆の順序でバイナリ表現が出力されます。再帰を使用すると、順序を簡単に修正できます。
#include <stdio.h>
void print_binary(int number)
{
if (number) {
print_binary(number >> 1);
putc((number & 1) ? '1' : '0', stdout);
}
}
私にとって、これは問題に対する最もクリーンな解決策の1つです。もし良かったら0b
接頭辞と末尾の改行文字、関数をラップすることをお勧めします。
putc('0'+(number&1), stdout);
@William Whyteの回答に基づくと、これは、、、およびバージョンを提供するマクロで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'
andの'0'
代わりに49
and を使用すると、より明確になり48
ます。また、b
最後の文字をヌルターミネーターのままにできるように、9文字の長さにする必要があります。
static char b[9] = {0}
。2.宣言をループの外に移動します。3 . int z,y;
最後のゼロを追加します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);
以前に投稿された回答のどれもが私が探していたものとまったく同じではないため、1つ作成しました。%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ビットまでのニーズを処理する必要があります。2つの関数pBinとpBinFillを作成しました。どちらも同じことを行いますが、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]
これまでの他のすべての回答には、これらの制限の少なくとも1つがあります。
戻りバッファに静的メモリを使用します。これにより、関数をの引数として使用できる回数が制限されますprintf()
。
ポインタを解放するために呼び出しコードを必要とするメモリを割り当てます。
呼び出しコードが適切なバッファを明示的に提供することを要求します。
printf()
直接お電話ください。これfprintf()
によりsprintf()
、to 、、、などの新しい関数が必要になります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
少しOTかもしれませんが、これがデバッグのためだけに必要な場合は、実行しているいくつかのバイナリ演算を理解または追跡するために、wcalc(単純なコンソール計算機)を調べてみてください。-bオプションを使用すると、バイナリ出力が得られます。
例えば
$ wcalc -b "(256 | 3)&0xff" = 0b11
ruby -e 'printf("%b\n", 0xabc)'
、dc
続いてが2o
続き0x123p
ます。
C標準ライブラリには、そのようなバイナリを出力するためのフォーマット関数はありません。printfファミリーがサポートするすべてのフォーマット操作は、人間が読めるテキストを対象としています。
次の再帰関数が役立つ場合があります。
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
です。一般に、1つ以上のオプションを指定する場合は、それを無限にします。4などの数値は問題を引き起こすだけでした。
標準ライブラリを使用して、任意の整数型をバイナリ文字列表現に一般的に変換する1つのステートメント:
#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を介して2進数を出力する方法」を参照してください。
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