Printing the binary representation of an unsigned char backwards? - c

How exactly does this code work? I'm confused about the first for loop since binary starts at 0 and as long as it is not equal to the binary representation of the char it will increase, so then binary is 1 and so on?
unsigned char c;
int binary;
scanf("%c", &c);
getchar();
printf("The decimal representation is: %d\n", c);
for (binary = 0; (1<<binary)<=c; binary++){ // moving to the left
} // until binary code matches c
printf("The backwards binary representation is: ");
for (int i=0; i<binary; i++){ // since we know the size
printf("%d", ((c>>i)&1)); // 1s and 0s are shifted to right
}
printf("\n");
return 0;

This:
for (binary = 0; (1<<binary)<=c; binary++)
simply counts how many significant bits are in the integer "c".
For instance, if "c" is 0101100 in binary, the most significant bit is the 6th from the right, and "binary" would be set to 6.
If "c" is 01 in binary, the most significant bit is the first from the right, and "binary" would be set to 1.
The biggest problem with this code is its almost useless comments.
If there must be comments, replace this:
/* moving to the left until binary code matches c */
with this:
/* Count number of significant bits.*/
Comments should say why the code is there, not describe how it works.
Comments like this don't serve any purpose:
/* since we know the size 1s and 0s are shift to right */
The second biggest problem is the variable names. "binary" is misleading. Call it "number_of_significant_bits" instead and the code almost doesn't need any comments.

Related

How to convert integer to binary form in C [duplicate]

This question already has answers here:
Is there a printf converter to print in binary format?
(57 answers)
Closed 3 years ago.
I'm trying to convert a user entered integer to binary form, but I keep getting a warning that "binary" is not initialized in the last printf statement.
#include <stdio.h>
int main(void)
{
long int integer, binary;
printf("Enter an integer: \n");
scanf("%ld", &integer);
while(integer != 0)
{
binary = integer % 2;
integer = integer / 2;
}
printf("The integer in binary is %ld", binary);
return 0;
}
Welcome to Stack Overflow.
The value binary is set during the while loop, but what happens if you actually enter a zero for the integer? In that case the loop doesn't run, and the value binary has no initialized value. Surprise!
That's why it's complaining.
However, the algorithm you're using, even if you enter a nonzero value, will only give binary the value of the lowest bit in the number you're converting, so you'll need different code to make it work to build up the binary value as you run through the integer.
Basically what you're trying to do is turn a binary value in to a kind of decimal representation of binary, which has enough limitations that I'm not sure it's worth doing.
Still:
long int binary = 0;
while (integer != 0)
{
binary += integer % 2; // 1 or 0
binary *= 10; // a "binary" decimal shift left
integer /= 2;
}
printf("Integer in binary is %ld", binary);
return 0;
}
This works, but it has a severe limitation of only being able to represent relatively small binary values.
The most common way people solve this exercise is to convert the integer value to a string rather than an integer, for easy display.
I wonder if that's the problem you're trying to solve?
An integer comprised of only decimal 1 and 0 digits is not binary. An int on a computer is already binary; the %d format specifier creates a character string representation of that value in decimal. It is mathematically nonsensical to generate a binary value that when represented as a decimal looks like some other binary value. Not least because that approach is good for only a 10 bit value (on a 32 bit int), or 19 bits using a 64bit int.
Moreover, the solution requires further consideration (and more code) to handle negative integer values - although how you do that is ambiguous due to the limited number of bits you can represent.
Since the int is already a binary value, it is far simpler to present the binary bit pattern directly than to calculate some decimal value that happens to resemble a binary value:
// Skip leading zero bits
uint32_t mask = 0x80000000u ;
while( mask != 0 && (integer & mask) == 0 ) mask >>= 1 ;
// Output remaining significant digits
printf("The integer in binary is ");
while( mask != 0 )
{
putchar( (integer & mask) == 0 ? '0' : '1' ) ;
mask >>= 1 ;
}
putchar( '\n' ) ;

Converting Decimal to Binary with long integer values C

My program is meant to convert decimal to binary by reading values from an input file and then outputting the binary values into an output file. Lets say the input file has these numbers:
190 31 5 891717742
Everything converts to binary just fine except for the 891717742. This outputs a value which is completely off of the binary output. Ive tried a LONG but they just output a negative value. For example this would output:
11000100 11110010 11 "1434923237" <- not right (not the actual binary values)
Decimal to Binary (from online):
char* convertDecimalToBinary(int n)
{
int binaryNumber = 0;
int remainder, i = 1;
static char buff[100];
while (n!=0)
{
remainder = n%2;
n /= 2;
binaryNumber += remainder*i;
i *= 10;
}
sprintf(buff, "%d", binaryNumber );
return buff;
}
The fundamental problem is that you're trying to use an int to store your binary representation. An int is just that, an integer. In memory it's represented in binary, but the C syntax allows you to use base 10 and base 16 literals when assigning or doing other operations on ints. This might make it seem like it's not being treated as a binary number, but it really is. In your program you are confusing the base 2 representation and the base 10 representation. 891717742 (base 10) converted to binary is 110101001001101000100001101110. What your algorithm is essentially trying to do is store the base 10 number 110101001001101000100001101110 in an int. That base 10 number is larger than even a 64 bit number, it would actually would take 97 bits to store.
Check it this answer to see how you can print out the binary representation of an int in C: Is there a printf converter to print in binary format?
It is pretty much easy, can be done in two easy steps.
Int to hex string
int main()
{
int n=891717742;
char buff[100];
sprintf(buff, "%x", n);
printf("\n buff=%s", buff);
return 0;
}
Hex to binary
Please look at this
How to convert a hexadecimal string to a binary string in C

32-bits as hex number in C with simple function call

I would like to know if I could get away with using printf to print 32 bits of incoming binary data from a microcontroller as a hexadecimal number. I already have collected the bits into an large integer variable and I'm trying "%x" option in printf but all I seem to get are 8-bit values, although I can't tell if that's a limitation with printf or my microcontroller is actually returning that value.
Here's my code to receive data from the microcontroller:
printf("Receiving...\n");
unsigned int n=0,b=0;
unsigned long lnum=0;
b=iolpt(1); //call to tell micro we want to read 32 bits
for (n=0;n<32;n++){
b=iolpt(1); //read bit one at a time
printf("Bit %d of 32 = %d\n",n,b);
lnum<<1; //shift bits in our big number left by 1 position
lnum+=b; //and add new value
}
printf("\n Data returned: %x\n",lnum); //always returns 8-bits
The iolpt() function always returns the bit read from the microcontroller and the value returned is a 0 or 1.
Is my idea of using %x acceptable for a 32-bit hexadecimal number or should I attempt something like "%lx" instead of "%x" to try to represent long hex even though its documented nowhere or is printf the wrong function for 32-bit hex? If its the wrong function then is there a function I can use that works, or am I forced to break up my long number into four 8-bit numbers first?
printf("Receiving...\n");
iolpt(1); // Tell micro we want to read 32 bits.
/* Is this correct? It looks pretty simple to be
initiating a read. It is the same as the calls
below, iolpt(1), so what makes it different?
Just because it is first?
*/
unsigned long lnum = 0;
for (unsigned n = 0; n < 32; n++)
{
unsigned b = iolpt(1); // Read bits one at a time.
printf("Bit %u of 32 = %u.\n", n, b);
lnum <<= 1; // Shift bits in our big number left by 1 position.
// Note this was changed to "lnum <<= 1" from "lnum << 1".
lnum += b; // And add new value.
}
printf("\n Data returned: %08lx\n", lnum);
/* Use:
0 to request leading zeros (instead of the default spaces).
8 to request a field width of 8.
l to specify long.
x to specify unsigned and hexadecimal.
*/
Fixed:
lnum<<1; to lnum <<= 1;.
%x in final printf to %08lx.
%d in printf in loop to %u, in two places.
Also, cleaned up:
Removed b= in initial b=iolpt(1); since it is unused.
Moved definition of b inside loop to limit its scope.
Moved definition of n into for to limit its scope.
Used proper capitalization and punctuation in comments to improve clarity and aesthetics.
Would something like that work for you?
printf("Receiving...\n");
unsigned int n=0,b=0;
unsigned long lnum=0;
b=iolpt(1); //call to tell micro we want to read 32 bits
for (n=0;n<32;n++){
b=iolpt(1); //read bit one at a time
printf("Bit %d of 32 = %d\n",n,b);
lnum<<1; //shift bits in our big number left by 1 position
lnum+=b; //and add new value
}
printf("\n Data returned: %#010lx\n",lnum); //now returns 32-bit

C program to find two's compliment

I came across a C code in a book to find the two's complement of a binary number. I wasn't familiar with the concept of one's and two's complement of a binary number so I did a thorough research and now understand a fair bit about the same. But I still have a few doubts about how the code works. The code is as follows (the comments were not there in the original code and have been added by me so that I could be corrected if it's wrong)-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
char a[16]; /*declaring an array to hold the binary number string*/
int i, j, k, len; /*len is the length of the string*/
printf ("Enter a binary number: ");
gets (a); /*reads the input string*/
len= strlen(a); /*calculates length of string*/
for (k=0; a[k]!='\0';k++) /*to check if its a valid binary number or not*/
{
if (a[k] != '0' && a[k]!='1')
{
printf ("\nIncorrect Binary format...this program will quit");
exit(0);
}
}
for (i=len-1; a[i]!='1'; i--) /* An empty for loop*/
;
for (j=i-1; j>=0; j--) /*checks from right to left if the bit is 0 or 1*/
{
if (a[j]=='1')
a[j]= '0'; /*if the bit is 1, its converted to 0*/
else
a[j]= '1'; /*if the bit is 0, its converted to 1*/
}
printf ("\n2's compliment = %s", a);
}
The code works absolutely fine, but I have doubts how.
First, I don't exactly understand what the empty for loop does. Does it counts till we encounter the first zero from the right side?
Second, in the third and last for loop, we just flip the value of each bit from 1 to 0 and from 0 to 1. But we do that for the one's complement, not the two's complement, right? We need to add 1 to the one's complement to find two's complement. The code dosen't seems to be doing that anywhere. How does it works then?
Kindly clearify, thanks in advance.
First, I don't exactly understand what the empty for loop does.
It is to find the rightmost 1 and assigns it to i.
Second, in the third and last for loop, we just flip the value of each
bit from 1 to 0 and from 0 to 1.
It is to flip all bits starting index i-1.
I have learnt the trick in my microprocessors course. It is that start read bits from right to left until see first bit which is 1. Don't flip it. After that, flip all bits.
Let's try, 10110 -> 01010
Start from right.
Read 0, it's not 1. Go ahead,
Read 1, yes, we get first bit which is 1. Don't flip it.
Read 1, flip it. Now it is 0.
Read 0, flip it. Now it is 1.
Read 1, flip it. Now it is 0.
We get 01010
The logic of the program is exactly what I mention.
Normally to compute the two's complement, we change all the 1's to 0's and all the 0's to 1, and then add 1.
Let's look at the two's complement of 172, or binary 10101100:
10101100
01010011 /* change all 0's to 1's and 1's to 0's */
01010100 /* add one */
Notice that when we added 1, we changed some of the 1's back to 0's. In fact, everything that had been a 0 at the right edge of the original number stayed 0. And the rightmost 1 in the original number stayed 1. And it was only the 1's and 0's to the left of the rightmost 1 that actually got swapped.
And that's what the mystery loop in the original program does. It scans from the right, skipping over 0's until it finds the first 1, and it's only the digits to the left of that point that it actually swaps. The variable i ends up holding the position of the rightmost 1, and then the next loop, the one that actually does the swapping, starts at j = i - 1.
One more thing: Sorry to nag about this, and you may know it already, but you really shouldn't use the gets() function, not even in a little test program. It's a truly horrid, dangerous function.

How to display hexadecimal numbers in C?

I have a list of numbers as below:
0, 16, 32, 48 ...
I need to output those numbers in hexadecimal as:
0000,0010,0020,0030,0040 ...
I have tried solution such as:
printf("%.4x",a); // where a is an integer
but the result that I got is:
0000, 0001, 0002, 0003, 0004 ...
I think I'm close there. Can anybody help as I'm not
so good at printf in C.
Thanks.
Try:
printf("%04x",a);
0 - Left-pads the number with
zeroes (0) instead of spaces, where
padding is specified.
4 (width) - Minimum number of
characters to be printed. If the
value to be printed is shorter than
this number, the result is right justified
within this width by padding on the left
with the pad character. By default this is
a blank space, but the leading zero we used
specifies a zero as the pad char.
The value is not truncated even if the result is
larger.
x - Specifier for hexadecimal
integer.
More here
i use it like this:
printf("my number is 0x%02X\n",number);
// output: my number is 0x4A
Just change number "2" to any number of chars You want to print ;)
Your code has no problem. It does print the way you want. Alternatively, you can do this:
printf("%04x",a);
You can use the following snippet code:
#include<stdio.h>
int main(int argc, char *argv[]){
unsigned int i;
printf("decimal hexadecimal\n");
for (i = 0; i <= 256; i+=16)
printf("%04d 0x%04X\n", i, i);
return 0;
}
It prints both decimal and hexadecimal numbers in 4 places with zero padding.

Resources