Use Integer#toBinaryString():
byte b1 = (byte) 129;
String s1 = String.format("%8s", Integer.toBinaryString(b1 & 0xFF)).replace(' ', '0');
System.out.println(s1); // 10000001
byte b2 = (byte) 2;
String s2 = String.format("%8s", Integer.toBinaryString(b2 & 0xFF)).replace(' ', '0');
System.out.println(s2); // 00000010
DEMO.
Answer from João Silva on Stack OverflowUse Integer#toBinaryString():
byte b1 = (byte) 129;
String s1 = String.format("%8s", Integer.toBinaryString(b1 & 0xFF)).replace(' ', '0');
System.out.println(s1); // 10000001
byte b2 = (byte) 2;
String s2 = String.format("%8s", Integer.toBinaryString(b2 & 0xFF)).replace(' ', '0');
System.out.println(s2); // 00000010
DEMO.
I used this. Similar idea to other answers, but didn't see the exact approach anywhere :)
System.out.println(Integer.toBinaryString((b & 0xFF) + 0x100).substring(1));
0xFF=255=0b11111111(max value for an unsigned byte)0x100=256=0b100000000
The & upcasts the byte to an integer. At that point, it can be anything from [0;255] ([0b00000000 ; 0b11111111], I excluded the leading 24 bits). Adding 0x100 and then .substring(1) ensure there will be leading zeroes.
I timed it compared to João Silva's answer, and this is over 10 times faster. http://ideone.com/22DDK1 I didn't include Pshemo's answer as it doesn't pad properly.
c - Bytes to binary conversion function - Code Review Stack Exchange
file - python how to convert bytes to binary - Stack Overflow
From Byte to Binary conversion [SOLVED]
How can I convert bytes object to decimal or binary representation in python? - Stack Overflow
Another way to do this is by using the bitstring module:
>>> from bitstring import BitArray
>>> input_str = '0xff'
>>> c = BitArray(hex=input_str)
>>> c.bin
'0b11111111'
And if you need to strip the leading 0b:
>>> c.bin[2:]
'11111111'
The bitstring module isn't a requirement, as jcollado's answer shows, but it has lots of performant methods for turning input into bits and manipulating them. You might find this handy (or not), for example:
>>> c.uint
255
>>> c.invert()
>>> c.bin[2:]
'00000000'
etc.
What about something like this?
>>> bin(int('ff', base=16))
'0b11111111'
This will convert the hexadecimal string you have to an integer and that integer to a string in which each byte is set to 0/1 depending on the bit-value of the integer.
As pointed out by a comment, if you need to get rid of the 0b prefix, you can do it this way:
>>> bin(int('ff', base=16))[2:]
'11111111'
... or, if you are using Python 3.9 or newer:
>>> bin(int('ff', base=16)).removeprefix('0b')
'11111111'
Note: using lstrip("0b") here will lead to 0 integer being converted to an empty string. This is almost always not what you want to do.
It's not terrible as it stands, but I think there are some ways it might be improved.
Include all needed files
The function needs several #include files that are not listed. Specifically, it needs these:
#include <stddef.h>
#include <stdio.h>
#include <limits.h>
It's important to list those, especially for a beginner.
Be careful with signed and unsigned
In the binary function, the compares an int iByte to a size_t nBytes, but size_t is unsigned and int is signed. Instead, declare both variables as size_t types, or better, see the next suggestion.
Count down instead of up
If we count down instead of up, not only do many compilers generate more efficient code, but we also avoid the signed/unsigned problem mentioned above.
Declare variables in as small a scope as practical
Putting all definitions at the top of the function is an antique style of C. In modern C (C99 and later) we declare variables as late as practical, ideally as they are defined, to avoid problems of uninitialized variables.
Use a bitmask directly instead of calculating
I would write the inner loop like this:
for(unsigned char mask = 1U << (CHAR_BIT-1); mask; mask >>= 1)
That makes it very clear that we're using a bitmask and how it is calculated and handled.
Use a convenience cast
Rather than casting p every time, I'd be inclined to declare an internal unsigned char * variable and use that instead.
Avoid encoding types in names
C is a statically typed language, so it is neither necessary nor desirable to encode the type within the name. See NL.5 for more. (Those are C++ guidelines, but this is equally applicable to C.)
Use pointers
Sooner or later, even beginners are going to need to learn how to use pointers. They have the considerable advantage here in simplifying the code.
Use const where practical
The function does not and should not modify the pointed-to value, so it's better to make that explicit and declare it const.
Consider separating the function into two
One way to think of this code is that it's printing one or more bytes with additional separators and formatting. That suggests an alternative which is to separate out the part that just prints the ones and zeroes from the loop.
Results
Here's the slightly refactored code using all of the suggestions above:
#include <stddef.h>
#include <stdio.h>
#include <limits.h>
void toBinary(const unsigned char *ptr) {
for(unsigned char mask = 1U << (CHAR_BIT-1); mask; mask >>= 1) {
putchar(*ptr & mask ? '1' : '0');
}
}
void binary(const void* p, size_t nBytes) {
for(const unsigned char* ptr = p; nBytes; --nBytes) {
putchar('[');
toBinary(ptr++);
putchar(']');
if(nBytes > 1) {
putchar('\t');
}
}
putchar('\n');
}
#define BINARY(x) binary(&x, sizeof x)
int main(void) {
char a = 85;
int b = 0x12345678;
BINARY(a);
BINARY(b);
}
Interface
I find it helps if we use verbs for function names. Instead of saying, "Here's some memory, let's binary() it," it's more natural to say, "Here's some memory, let's print() it." Now obviously print is much too general a name in C that has no overloading or namespaces, so we'd have to qualify: print_as_binary().
Since we don't plan to modify the pointed-to variable, we should accept p as a pointer to const void.
size_t is absolutely the right choice for a count variable such as nBytes.
Implementation
We don't need to create iBit and iByte up-front like that in modern C. We can give them smaller scope by declaring them within their respective for initialisations.
iByte really ought to match the type of nBytes - comparing signed and unsigned types is tricky, and we need to have at least the same range as what's passed to the function. The type of iBit doesn't matter, as we know that CHAR_BIT will be well within its range, regardless.
for (size_t iByte = 0; iByte < nBytes; iByte++)
When choosing the character to print, we could take advantage of the fact that C guarantees that 0 and 1 will have consecutive character codes:
putchar('0' + (bit & 1));
It's probably easier to print the separator string before the data, as that makes for a simpler test (iByte != 0).
We might want to assign p to an unsigned char* variable rather than explicitly casting it in the loop.
It's very surprising to see binary numbers written backwards like that. The standard convention in mathematics and programming is to write the most-significant bit first.
The macro
It's good practice to wrap all expansions of macro arguments within parentheses, so that if we are passed an expression, it is treated as a single unit:
#define BINARY(x) binary(&(x), sizeof (x))
Modified code:
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
void print_as_binary(const void *p, size_t nBytes)
{
const unsigned char *const q = p;
putchar('[');
for (size_t iByte = 0; iByte < nBytes; ++iByte) {
if (iByte) {
fputs("]\t[", stdout);
}
for (int iBit = CHAR_BIT; iBit > 0; --iBit) {
int bit = q[iByte] >> (iBit - 1);
putchar('0' + (bit & 1));
}
}
printf("]\n");
}
#define PRINT_AS_BINARY(x) print_as_binary(&(x), sizeof (x))
int main(void)
{
int t = 1000000;
PRINT_AS_BINARY(t);
}
Starting from Python 3.2, you can use int.from_bytes.
Second argument, byteorder, specifies endianness of your bytestring. It can be either 'big' or 'little'. You can also use sys.byteorder to get your host machine's native byteorder.
import sys
int.from_bytes(b'\x11', byteorder=sys.byteorder) # => 17
bin(int.from_bytes(b'\x11', byteorder=sys.byteorder)) # => '0b10001'
Iterating over a bytes object gives you 8 bit ints which you can easily format to output in binary representation:
import numpy as np
>>> my_bytes = np.random.bytes(10)
>>> my_bytes
b'_\xd9\xe97\xed\x06\xa82\xe7\xbf'
>>> type(my_bytes)
bytes
>>> my_bytes[0]
95
>>> type(my_bytes[0])
int
>>> for my_byte in my_bytes:
>>> print(f'{my_byte:0>8b}', end=' ')
01011111 11011001 11101001 00110111 11101101 00000110 10101000 00110010 11100111 10111111
A function for a hex string representation is builtin:
>>> my_bytes.hex(sep=' ')
'5f d9 e9 37 ed 06 a8 32 e7 bf'