Bitwise Operators on a binary representation in C [closed] - c

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a binary representation of a number as a char array which is at most 18 bits long. I need to store the three bits on the right, and the remaining bits into two different strings using bitwise operators.
For example, I have a char array containing "00000000011101". I need a function that will store "101" (the last three bits) and store "00000000011" (the remaining bits).
However, this must be done using bitwise operators. So I understand that I need to convert the strings to int, and then shift but I'm not sure how to go about this.
Your help would be very much appreciated.

Converting the string to int is easy: start with a zero int, then go through the characters of the binary representation, and check if it is zero or one. First, shift the partial result to the left. Then, if the digit is one, OR the result with 1. Continue to the next character. When you see null terminator '\0', stop.
Here is some pseudocode:
res = 0
ptr = "00000000011101"
while ptr is not pointing to '\0'
res <<= 1;
if ptr points to '1'
res |= 1;
Once you have your int, getting the last three bits is equivalent to AND-ing & the result with seven (its binary representation is 0000111). Getting the rest of the bits is equivalent to shifting >> the number right by three.
Here is some pseudocode:
lastThree = res & 7
topBits = res >> 3

You can always do it yourself. It's actually pretty simple.
int BitwiseOr(char str1[], char str2[]) //Although it probably works on not whole numbers too.
{
int i, output = 0;
char* outputstr = malloc(sizeof(char)(strlen(str1)>strlen(str2)?strlen(str1):strlen(str2))); //Although size of char is mostly 1. It's defined to fit to the biggest string size (binary representation there is).
char* rstr1;
char* rstr2;
if(strlen(str1)==strlen(str2)
{
rstr1 = str1; //Point to the same address.
rstr2 = str2; //As we are going to use these variables for cases if the strings' length aren't equal and we need to add zeros to the left.
}
else if(strlen(str1)>strlen(str2)
{
rstr1 = str1;
rstr2 = malloc(sizeof(char)*strlen(str1));
for(i = 0 ; i < strlen(str1)-strlen(str2) ; i++)
{
rstr2[i] = '0';
}
for(i = i /*To be one spot after the first loop was at*/ ; i < strlen(str1) ; i++)
{
rstr2[i] = str1[i];
}
}
else
{
rstr1 = malloc(sizeof(char)*strlen(str2));
rstr2 = str2;
for(i = 0 ; i < strlen(str2)-strlen(str1) ; i++)
{
rstr1[i] = '0';
}
for(i = i /*To be one spot after the first loop was at*/ ; i < strlen(str1) ; i++)
{
rstr1[i] = str1[i];
}
}
/*After memory is allocated*/
for(i = 0 ; i < strlen(outputstr) ; i++)
{
outputstr[i] = (str1[i]-'0') || (str2[i]-'0');
}
/*Now turn the number from binary string to decimal - pretty simple. Just go from the right to the left with powers of 2 when the first is 2 powered by zero and so on and when it's '1' in the output string - add to the output integer the 2 powered by the spot from the right*/
return output;
}
Some explanation of Bitwise Operators and uses and all.
Bitwise operators actually use the binary representation of a number and perform an action on it with another number. Example would be OR, as above. Takes all the bits, and just OR them all and get a number. What is it useful for? Actually tons of stuff. Working with graphics and colors especially, OpenGL uses them when setting a window, it defines constants and you send the Bitwise OR solution of them - and that way it knows all of the options you chose by knowing the possible option.

Here's a working C program to demonstrate a possible solution:
#include <stdio.h>
#include <string.h>
main()
{
int i;
unsigned int res = 0;
unsigned int bitmask = 1;
static unsigned char *ptr = "00000000011101";
printf("ptr = %s\n", ptr);
for (i=(strlen(ptr) -1); i>0; i--) {
printf("ptr[%d] = %c (bitmask = 0x%0x)\n", i, ptr[i], bitmask);
if (ptr[i] == '1')
res = (res | bitmask);
bitmask <<= 1;
}
printf("res = 0x%x\n", res);
}

Related

User-defined function without printf, returns hexadecimal value

char decimalToHexadecimal(long int decimalNumber)
{
long int quotient;
long int remainder;
static char hexDecNum[100];
int i=0;
quotient = decimalNumber;
while (quotient != 0)
{
remainder = quotient % 16;
// to convert integer into character
if (remainder < 10)
{
remainder = remainder + 48;
}
else
{
remainder = remainder + 55;
}
hexDecNum[i++] = remainder;
quotient = quotient / 16;
}
}
This user defined function will convert decimal number to hexadecimal number.
I wanted to make function that will not use any library function like printf,scanf etc. I and to get return hexadecimal value of a decimal number from this function.
But, I am confused how to get return hexadecimal number from this function?
It's better to use an explicit string of the desired character set, that way you can remove any assumptions about the encoding, which is very good for portability.
Although C requires that the digits 0 through 9 are encoded using adjacent code points (i.e. '1' - '0' must equal 1, and so on), no such guarantee is made for the letters.
Also, returning a string requires heap allocation, a static buffer (which makes the function harder to use), or simply accepting the string from the caller which is often the best choice.
It's important to realize that the typical technique of extracting the remainder from division by 16 (or just masking out the four right-most bits) generates bits "from the right", whereas typical string-building runs from the left. This has to be taken into account as well, or you'd generate "d00f" when given 0xf00d.
Here's how it could look:
char * num2hex(char *buf, size_t buf_max, unsigned long number)
{
if(buf_max < 2)
return NULL;
char * put = buf + buf_max; // Work backwards.
*--put = '\0'; // Terminate the resulting string.
do
{
if(put == buf)
return NULL;
const unsigned int digit = number & 15;
*--put = "0123456789abcdef"[digit];
number >>= 4;
} while(number != 0);
return put;
}
This function returns the start of the built string (which is "right-aligned" in the provided buffer, so it's not at the start of it), or NULL if it runs out of space.
Note: yeah, this is perhaps a bit too terse, of course the digit set could be extracted out and given a name, but it's also pretty obvious what its purpose is, and indexing a literal is handy (some people don't seem to realize it's doable) and somewhat instructive to show off.
Read the chapter about strings in your C textbook.
One solution is to return a pointer to char:
char *decimalToHexadecimal(long int decimalNumber)
{
long int quotient;
long int remainder;
static char hexDecNum[100]; // must be static
quotient = decimalNumber;
int i = 0; // // <<<< you forgot to declare i
while (quotient != 0)
{
remainder = quotient % 16;
// to convert integer into character
if (remainder < 10)
{
remainder = remainder + 48;
}
else
{
remainder = remainder + 55;
}
hexDecNum[i++] = remainder;
quotient = quotient / 16;
}
hexDecNum[i] = 0; // <<< you forgot the NUL string terminator
return hexDecNum; // <<< you forgot to return something
}
int main()
{
printf("%s\n", decimalToHexadecimal(0x1234));
}
The hexDecNum buffer must be static, because you are returning a pointer to this buffer, and this buffer will cease to exist once you have returned from the decimalToHexadecimal function, because it's a local variable. Modern compilers will usually emit a warning if you return the address of a local variable.
The function is still not quite what you want. I leave it as an exercise to correct it.
Edit
Another approach for conversion is this: the decimal number is actually represented as a binary number (as all numbers BTW), so we don't even need division; we just can decompose the number into 4 bit nibbles (0000 to 1111) and transform these nibbles into a hexadecimal digits (0..9, A..F):
char *decimalToHexadecimal(long int decimalNumber)
{
static char hexDecNum[100];
int i;
for (i = 0; i < sizeof(decimalNumber) * 2; i++)
{
int digit = decimalNumber & 0xf;
if (digit >= 10)
digit += 'A' - 10; // better than writing 55
else
digit += '0'; // better than writing 48
hexDecNum[i] = digit;
decimalNumber >>= 4;
}
hexDecNum[i] = 0;
return hexDecNum;
}
The function suffers from the same problem as your original function. Improving it is left as an exercise.

Print a Char Array of Integers in C

For class, I am required to create a function that converts an Integer into it's corresponding Binary number. However, I am forced to use the given main and parameters for the to_binary function. The whole problem requires me to print out the 32 bit binary number, but to break it up, I am just trying to print out the Char Array, that I thought I filled with Integers (perhaps the issue). When I do compile, I receive just a blank line (from the \n) and I am wondering how I can fix this. All I want to do is to be able to print the binary number for 5 ("101") yet I can't seem to do it with my professor's restrictions. Remember: I cannot change the arguments in to_binary or the main, only the body of to_binary. Any help would be greatly appreciated.
#include<stdio.h>
void to_binary(int x, char c[]) {
int j = 0;
while (x != 0) {
c[j] x = x % 2;
j++;
}
c[33] = '\0';
}
int main() {
int i = 5;
char b[33];
to_binary(i,b);
printf("%s\n", b);
}
This is the answer to your question.
void to_binary(int x, char c[]) {
int i =0;
int j;
while(x) {
/* The operation results binary in reverse order.
* so right-shift the entire array and add new value in left side*/
for(j = i; j > 0; j--) {
c[j] = c[j-1];
}
c[0] = (x%2) + '0';
x = x/2;
i++;
}
c[i]=0;
}
the problem is in the code below:
while (x != 0) {
c[j] = x % 2; // origin: c[j] x = x % 2; a typo?
j++;
}
the result of x % 2 is a integer, but you assigned it to a character c[j] —— integer 1 is not equal to character '1'.
If you want to convert a integer(0-9) to a character form, for example: integer 7 to character '7', you can do this:
int integer = 7;
char ch = '0' + integer;
One of the previous answers has already discussed the issue with c[j] x = x % 2; and the lack of proper character conversion. That being said, I'll instead be pointing out a different issue. Note that this isn't a specific solution to your problem, rather, consider it to be a recommendation.
Hard-coding the placement of the null-terminator is not a good idea. In fact, it can result in some undesired behavior. Imagine I create an automatic char array of length 5. In memory, it might look something like this:
Values = _ _ _ _ _
Index = 0 1 2 3 4
If I were to populate the first three indexes with '1', '0', and '1', the array might look like so:
Values = 1 0 1 _ _
Index = 0 1 2 3 4
Let's say I set index 4 to contain the null-terminator. The array now looks like so:
Values = 1 0 1 _ \0
Index = 0 1 2 3 4
Notice how index three is an open slot? This is bad. In C/C++ automatic arrays contain garbage values by default. Furthermore, strings are usually printed by iterating from character to character until a null-terminator is encountered.
If the array were to look like it does in the previous example, printing it would yield a weird result. It would print 1, 0, 1, followed by an odd garbage value.
The solution is to set the null-terminator directly after the string ends. In this case, you want your array to look like this:
Values = 1 0 1 \0 _
Index = 0 1 2 3 4
The value of index 4 is irrelevant, as the print function will terminate upon reading index 3.
Here's a code example for reference:
#include <stdio.h>
int main() {
const size_t length = 4;
char binary[length];
size_t i = 0;
while (i < length - 1) {
char c = getchar();
if (c == '0' || c == '1')
binary[i++] = c;
}
binary[i] = '\0';
puts(binary);
return 0;
}
#include<stdio.h>
int binary(int x)
{
int y,i,b,a[100];
if(x<16)
{
if(x%2==1)
a[3]=1;
if(x/2==1||x/2==3 || x/2==5 || x/2==7)
a[2]=1;
if(x>4 && x<8)
a[1]=1;
else if(x>12 && x<16)
a[1]=1;
if(x>=8)
a[0]=1;
}
for(i=0;i<4;i++)
printf("\t%d",a[i]);
printf("\n");
}
int main()
{
int c;
printf("Enter the decimal number (less than 16 ):\n");
scanf("%d",&c);
binary(c);
}
this code might help it will simply convert the decimal number less than 16 into the 4 digit binary number.if it contains any error than let me know

Storing bits from an array in an integer

So i have an array of bits, basically 0's and 1's in a character array.
Now what I want to do is store these bits in an integer I have in another array (int array), but I'm not sure how to do this.
Here is my code to get the bits:
char * convertStringToBits(char * string) {
int i;
int stringLength = strlen(string);
int mask = 0x80; /* 10000000 */
char *charArray;
charArray = malloc(8 * stringLength + 1);
if(charArray == NULL) {
printf("An error occured!\n");
return NULL; //error - cant use charArray
}
for(i = 0; i < stringLength; i++) {
mask = 0x80;
char c = string[i];
int x = 0;
while(mask > 0) {
char n = (c & mask) > 0;
printf("%d", n);
charArray[x++] = n;
mask >>= 1; /* move the bit down */
}
printf("\n");
}
return charArray;
}
This gets a series of bits in an array {1, 0, 1, 1, 0, 0, 1} for example. I want to store this in the integers that I have in another array. I've heard about integers having unused space or something.
For Reference: The integer values are red values from the rgb colour scheme.
EDIT:
To use this I would store this string in the integer values, later to be decoded the same way to retrieve the message (steganography).
So you want to do LSB substitution for the integers, the simplest form of steganography.
It isn't that integers have unused space, it's just that changing the LSB changes the value of an integer by 1, at most. So if you're looking at pixels, changing their value by 1 won't be noticeable by the human eye. In that respect, the LSB holds redundant information.
You've played with bitwise operations. You basically want to clear the last bit of an integer and substitute it with the value of one of your bits. Assuming your integers range between 0 and 255, you can do the following.
pixel = (pixel & 0xfe) | my_bit;
Edit: Based on the code snippet from the comments, you can achieve this like so.
int x;
for (x = 0; x < messageLength; x++) {
rgbPixels[x][0] = (rgbPixels[x][0] & 0xfe) | bitArray[x];
}
Decoding is much simpler, in that all you need to do is read the value of the LSB of each pixel. The question here is how will you know how many pixels to read? You have 3 options:
The decoder knows the message length in advance.
The message length is similarly hidden in some known location so that the decoder can extract it. For example, 16 bits representing in binary the message length, which is hidden in the first 16 pixels before bitArray.
You use an end-of-message marker, where you keep extracting bits until you hit a signature sequence that signals you to stop. For example, eight 0s in a row. You must make sure that how long the sequence and whatever it will be, it mustn't be encountered prematurely in your bit array.
So say somehow you have allocated the size for the message length. You can simply get extract your bit array (after allocation) like so.
int x;
for (x = 0; x < messageLength; x++) {
bitArray[x] = rgbPixels[x][0] & 0x01;
}
This converts a string to the equivalent int.
char string[] = "101010101";
int result = 0;
for (int i=0; i<strlen(string); i++)
result = (result<<1) | string[i]=='1';

how to store the value of a variable to string array?

Here I have created a string and I am storing the binary value of a number in the string.. I want to store the value of the variable num to the string.
i contains the length of the binary number for the given decimal number..suppose the given number is A=6, i contains 3 and i need a string 'result' having '110' which is the binary value of 6.
char* result = (char *)malloc((i)* sizeof(char));
i--;
while(A>=1)
{
num=A%2;
result[i]=num; // here I need to store the value of num in the string
A=A/2;
i--;
}
It appears from the code you've posted is that what you are trying to do is to print a number in binary in a fixed precision. Assuming that's what you want to do, something like
unsigned int mask = 1 << (i - 1);
unsigned int pos = 0;
while (mask != 0) {
result[pos] = (A & mask) == 0 ? '0' : '1';
++pos;
mask >>= 1;
}
result[pos] = 0; //If you need a null terminated string
edge cases left as an exercise for the reader.
I'm not sure specifically what you are asking for. Do you mean the binary representation (i.e. 00001000) of a number written into a string or converting the variable to a string (i.e. 8)? I'll assume you mean the first.
The easiest way to do this is to repeatedly test the least significant bit and shift the value to the right (>>). We can do this in for loop. However you will need to know how many bits you need to read. We can do this with sizeof.
int i = 15;
for (int b = 0; b < sizeof(i); ++b) {
uint8_t bit_value = (i & 0x1);
i >>= 1;
}
So how do we turn this iteration into a string? We need to construct the string in reverse. We know how many bits are needed, so we can create a string buffer accordingly with an extra byte for NULL termination.
char *buffer = calloc(sizeof(i) + 1, sizeof(char));
What this does is allocates memory that is sizeof(i) + 1 elements long where each element is sizeof(char), and then zero's each element. Now lets put the bits into the string.
for (int b = 0; b < sizeof(i); ++b) {
uint8_t bit_value = (i & 0x1);
size_t offset = sizeof(i) - 1 - b;
buffer[offset] = '0' + bit_value;
i >>= 1;
}
So what's happening here? In each pass we're calculating the offset in the buffer that we should be writing a value to, and then we're adding the ASCII value of 0 to bit_value as we write it into the buffer.
This code is untested and may have some issues, but that is left as an exercise to the reader. If you have any questions, let me know!
here is the whole code. It is supposed to work fine.
int i=0;
int A;//supposed entered by user
//calculating the value of i
while(A!=0)
{
A=A/2;
i++;
}
char* result=(char *)malloc(sizeof(char)*i);
i--;
while(A!=0)
{
result[i]='0'+(A%2);
A=A/2;
i--;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
char *numToBinStr(int num){
static char bin[sizeof(int) * CHAR_BIT + 1];
char *p = &bin[sizeof(int) * CHAR_BIT];//p point to end
unsigned A = (unsigned)num;
do {
*--p = '0' + (A & 1);
A >>= 1;
}while(A > 0);//do-while for case value of A is 0
return p;
}
int main(void){
printf("%s\n", numToBinStr(6));
//To duplicate, if necessary
//char *bin = strdup(numToBinStr(6));
char *result = numToBinStr(6);
char *bin = malloc(strlen(result) + 1);
strcpy(bin, result);
printf("%s\n", bin);
free(bin);
return 0;
}
You could use these functions in <stdlib.h>:
itoa(); or sprintf()
The second link has some examples as well.

Conversion of Char to Binary in C

I am trying to convert a character to its binary representation (so character --> ascii hex --> binary).
I know to do that I need to shift and AND. However, my code is not working for some reason.
Here is what I have. *temp points to an index in a C string.
char c;
int j;
for (j = i-1; j >= ptrPos; j--) {
char x = *temp;
c = (x >> i) & 1;
printf("%d\n", c);
temp--;
}
We show up two functions that prints a SINGLE character to binary.
void printbinchar(char character)
{
char output[9];
itoa(character, output, 2);
printf("%s\n", output);
}
printbinchar(10) will write into the console
1010
itoa is a library function that converts a single integer value to a string with the specified base.
For example... itoa(1341, output, 10) will write in output string "1341".
And of course itoa(9, output, 2) will write in the output string "1001".
The next function will print into the standard output the full binary representation of a character, that is, it will print all 8 bits, also if the higher bits are zero.
void printbincharpad(char c)
{
for (int i = 7; i >= 0; --i)
{
putchar( (c & (1 << i)) ? '1' : '0' );
}
putchar('\n');
}
printbincharpad(10) will write into the console
00001010
Now i present a function that prints out an entire string (without last null character).
void printstringasbinary(char* s)
{
// A small 9 characters buffer we use to perform the conversion
char output[9];
// Until the first character pointed by s is not a null character
// that indicates end of string...
while (*s)
{
// Convert the first character of the string to binary using itoa.
// Characters in c are just 8 bit integers, at least, in noawdays computers.
itoa(*s, output, 2);
// print out our string and let's write a new line.
puts(output);
// we advance our string by one character,
// If our original string was "ABC" now we are pointing at "BC".
++s;
}
}
Consider however that itoa don't adds padding zeroes, so printstringasbinary("AB1") will print something like:
1000001
1000010
110001
unsigned char c;
for( int i = 7; i >= 0; i-- ) {
printf( "%d", ( c >> i ) & 1 ? 1 : 0 );
}
printf("\n");
Explanation:
With every iteration, the most significant bit is being read from the byte by shifting it and binary comparing with 1.
For example, let's assume that input value is 128, what binary translates to 1000 0000.
Shifting it by 7 will give 0000 0001, so it concludes that the most significant bit was 1. 0000 0001 & 1 = 1. That's the first bit to print in the console. Next iterations will result in 0 ... 0.
Your code is very vague and not understandable, but I can provide you with an alternative.
First of all, if you want temp to go through the whole string, you can do something like this:
char *temp;
for (temp = your_string; *temp; ++temp)
/* do something with *temp */
The term *temp as the for condition simply checks whether you have reached the end of the string or not. If you have, *temp will be '\0' (NUL) and the for ends.
Now, inside the for, you want to find the bits that compose *temp. Let's say we print the bits:
for (as above)
{
int bit_index;
for (bit_index = 7; bit_index >= 0; --bit_index)
{
int bit = *temp >> bit_index & 1;
printf("%d", bit);
}
printf("\n");
}
To make it a bit more generic, that is to convert any type to bits, you can change the bit_index = 7 to bit_index = sizeof(*temp)*8-1

Resources