It's hilarious that C doesn't provide native functions to display numbers in binary form, or to change single bits.
Here is a solution that uses inline assembly to provide:
- bin$(*number, size)
. bchg(*Number, bitpos)
The examples are for integers and long longs but both function should work for integers of any size (test yourself - the usual disclaimers apply).
#include <stdio.h> // display numbers in binary form, and manipulate single bits
#pragma warn(disable:2007) // assembly not portable
char buffer [1000]; // could be a big number ;-)
char* bin$(int Number, int ct) {
_asm {
push esi
push edi
mov esi, Number
mov edi, offset buffer
mov ecx, ct
lea esi, [esi+ecx]
shl ecx, 3 ; bytes to bits
L0:
test ecx, 31
jne L1
mov al, 32
stosb
sub esi, 4
mov eax, [esi]
xchg eax, edx
L1:
shl edx, 1
setc al
add al, 48
stosb
dec ecx
ja L0
xor eax, eax
stosd
pop edi
pop esi
}
return buffer;
}
void bchg (int Number, int bitpos) {
_asm {
push esi
mov esi, Number
mov ecx, bitpos
mov edx, ecx
shr edx, 3 ; bits to bytes
add esi, edx
lodsd ; get bits
shl edx, 3
sub ecx, edx ; get bitpos
ror eax, cl
btc eax, 0
rol eax, cl
mov [esi-4], eax
pop esi
}
}
int main(void) {
unsigned long long MyLL=0x88AACCEE99ABCDEF;
unsigned int MyInt=0x88AACCEE;
int pNumber;
pNumber=(int)&MyLL;
printf("The number has %i bytes and %i bits\n", sizeof(MyLL), sizeof(MyLL) * 8 );
printf("binary: %s\n", bin$(pNumber, sizeof(MyLL)));
printf("expected: %s\n\n", "10001000101010101100110011101110 10011001101010111100110111101111");
bchg(pNumber, 2); // change the third-last bit
bchg(pNumber, sizeof(MyLL)*8-3); // change the third bit
printf("binary: %s\n", bin$(pNumber, sizeof(MyLL)));
printf("expected: %s\n\n", "10101000101010101100110011101110 10011001101010111100110111101011");
pNumber=(int)&MyInt;
printf("The number has %i bytes and %i bits\n", sizeof(MyInt), sizeof(MyInt) * 8 );
printf("binary: %s\n", bin$(pNumber, sizeof(MyInt)));
printf("expected: %s\n\n", "10001000101010101100110011101110");
bchg(pNumber, 2);
bchg(pNumber, sizeof(MyInt)*8-3);
printf("binary: %s\n", bin$(pNumber, sizeof(MyInt)));
printf("expected: %s\n\n", "10101000101010101100110011101010");
}
Output:
The number has 8 bytes and 64 bits
binary: 10001000101010101100110011101110 10011001101010111100110111101111
expected: 10001000101010101100110011101110 10011001101010111100110111101111
binary: 10101000101010101100110011101110 10011001101010111100110111101011
expected: 10101000101010101100110011101110 10011001101010111100110111101011
The number has 4 bytes and 32 bits
binary: 10001000101010101100110011101110
expected: 10001000101010101100110011101110
binary: 10101000101010101100110011101010
expected: 10101000101010101100110011101010