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

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' ) ;

Related

Using an unsigned int in a do-while loop

I'm new to coding in c and I've been trying to wrap my head around unsigned integers. This is the code I have:
#include <stdio.h>
int main(void)
{
unsigned int hours;
do
{
printf("Number of hours you spend sleeping a day: ");
scanf(" %u", &hours);
}
while(hours < 0);
printf("\nYour number is %u", hours);
}
However, when I run the code and use (-1) it does not ask the question again like it should and prints out (Your number is 4294967295) instead. If I change unsigned int to a normal int, the code works fine. Is there a way I can change my code to make the unsigned int work?
Appreciate any help!
Is there a way I can change my code to make the unsigned int work?
Various approaches possible.
Read as int and then convert to unsigned.
Given "Number of hours you spend sleeping a day: " implies a small legitimate range about 0 to 24, read as int and convert.
int input;
do {
puts("Number of hours you spend sleeping a day:");
if (scanf("%d", &input) != 1) {
Handle_non_text_input(); // TBD code for non-numeric input like "abc"
}
} while (input < 0 || input > 24);
unsigned hours = input;
An unsigned int cannot hold negative numbers. It is useful since it can store a full 32 bit number (twice as large as a regular int), but it cannot hold negative numbers So when you try to read your negative unsigned int, it is being read as a positive number. Although both int and unsigned int are 32 bit numbers, they will be interpreted much differently.
I would try the next test:
do:{
printf("enter valid input...")
scanf("new input...")
} while (hours > 24)
Why should it work?
An unsigned int in C is a binary number, with 32 bit. that means it's max value is 2^32 - 1.
Note that:
2^32 - 1 == 4294967295. That is no coincidence. Negative ints are usually represented using the "Two's complement" method.
A word about that method:
When I use a regular int, it's most significant bit is reserved for sign: 1 if negative, 0 if positive. A positive int than holds a 0 in it's most significant bit, and 1's and 0's on the remaining coordinates in the ordinary binary manner.
Negative ints, are represented differently:
Suppose K is a positive number, represented by N bits.
The number (-K) is represented using 1 in the most significant bit, and the POSITIVE NUMBER: (2^(N-1) - K) occupying the N-1 least significant bits.
Example:
Suppose N = 4, K = 7. Binary representation for 7 using 4 bit:
7 = 0111 (The most significant bit is reserved for sign, remember?)
-7 , on the other hand:
-7 = concat(1, 2^(4-1) - 7) == 1001
Another example:
1 = 0001, -1 = 1111.
Note that if we use 32 bits, -1 is 1...1 (altogether we have 32 1's). This is exactly the binary representation of the unsigned int 4294967295. When you use unsigned int, you instruct the compiler to refer to -1 as a positive number. This is where your unexpected "error" comes from.
Now - If you use the while(hours>24), you rule out most of the illegal input. I am not sure though if you rule out all illegal input. It might be possible to think of a negative number such that the compiler interpret it as a non-negative number in the range [0:24] when asked to ignore the sign, and refer to the most significant bit as 'just another bit'.

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

Array contains garbage values not input values

I am writing a basic program to compute the binary eq of a decimal value. I'm storing the individual bits or 0 and 1 values into an array so I can eventually reverse the array and print the accurate binary representation. However when I print the array contents to check if array has been properly filled I see garbage values, or 0 if arr[]={0}
My code
int main() {
int i = 0, j = 0, k, decimal, binary = 0, remainder, divider;
int bin[10];
printf("Enter decimal value");
scanf("%d", &decimal);
while ((decimal != 0) && (i < decimal)) {
remainder = decimal % 2;
decimal = decimal / 2;
bin[i] = remainder;
j++;
printf("%d", bin[i]);
}
printf("\n%d", j);
printf("\n%d", bin[0]);
printf("\n%d", bin[1]);
printf("\n%d", bin[2]);
printf("\n%d", bin[3]);
printf("%d", bin);
return 0;
}
.exe
enter image description here
If you are still having problems with the conversion, it may be helpful to consider a couple of points. First, you are over-thinking the conversion from decimal to binary. For any given integer value, the value is already stored in memory in binary.
For example, when you have the integer 10, the computer stores it as 1010 in memory. So for all practical purposes, all you need to do is read the memory for value and set your array values to 1 for each bit that is 1 and 0 for each bit that is 0. You can even go one better, since what you are most likely after is the binary representation of the number, there is no need to store the 1s and 0s as a full 4-byte integer value in bin, why not make bin a character array and store the characters '1' or '0' in the character array (which when nul-terminated) allows a simple printing of the binary representation as a string.
This provides several benefits. Rather than converting from base 10 to base 2 and the divisions and modulo calls required for the base conversion, you can simply shift decimal to the right by one and check whether the least-significant-bit is 0 or 1 and store the desired character '0' or '1' based on the results of a simple unary and operation.
For example, in you case with an integer, you can determine the number of bits required to represent any integer value in binary with sizeof (int) * CHAR_BIT (where CHAR_BIT is a constant provided in limits.h and specifies the number of bits in a character (e.g. byte)). For an integer you could use:
#include <stdio.h>
#include <limits.h> /* for CHAR_BIT */
#define NBITS sizeof(int) * CHAR_BIT /* constant for bits in int */
To store the character representations of the binary number (or you could store the integers 1, 0 if desired), you can simply declare a character array:
char bin[NBITS + 1] = ""; /* declare storage for NBITS + 1 char */
char *p = bin + NBITS; /* initialize to the nul-terminating char */
(initialized to all zero and the +1 to allow for the nul-terminating character to allow the array to be treated as a string when filled)
Next, as you have discovered, whether you perform the base conversion or shift and and the resulting order of the individual bit values will be in reverse order. To handle that, you can simply declare a pointer pointing to the last character in your array and fill the array with 1s and 0s from the back toward the front.
Here too the character array/string representation makes things easier. Having initialized your array to all zero, you can start writing to your array beginning at the next to last character and working from the end to the beginning will insure you have a nul-terminated string when done. Further, regardless of the number of bits that make up decimal, you are always left with a pointer to the start of the binary representation.
Depending on how you loop over each bit in decimal, you may need to handle the case where decimal = 0; separately. (since you loop while there are bits in decimal, the loop won't execute if decimal = 0;) A simple if can handle the case and your else can simply loop over all bits in decimal:
if (decimal == 0) /* handle decimal == 0 separately */
*--p = '0';
else /* loop shifting decimal right by one until 0 */
for (; decimal && p > bin; decimal >>= 1)
*--p = (decimal & 1) ? '1' : '0'; /* decrement p and set
* char to '1' or '0' */
(note: since p was pointing to the nul-terminating character, you must decrement p with the pre-decrement operator (e.g. --p) before dereferencing and assigning the character or value)
All that remains is outputting your binary representation, and if done as above, it is a simple printf ("%s\n", p);. Putting all the pieces together, you could do something like the following:
#include <stdio.h>
#include <limits.h> /* for CHAR_BIT */
#define NBITS sizeof(int) * CHAR_BIT /* constant for bits in int */
int main (void) {
int decimal = 0;
char bin[NBITS + 1] = ""; /* declare storage for NBITS + 1 char */
char *p = bin + NBITS; /* initialize to the nul-terminating char */
printf ("enter a integer value: "); /* prompt for input */
if (scanf ("%d", &decimal) != 1) { /* validate ALL user input */
fputs ("error: invalid input.\n", stderr);
return 1;
}
if (decimal == 0) /* handle decimal == 0 separately */
*--p = '0';
else /* loop shifting decimal right by one until 0 */
for (; decimal && p > bin; decimal >>= 1)
*--p = (decimal & 1) ? '1' : '0'; /* decrement p and set
* char to '1' or '0' */
printf ("binary: %s\n", p); /* output the binary string */
return 0;
}
(note: the comment on validating ALL user input -- especially when using the scanf family of functions. Otherwise you can easily stray off into Undefined Behavior on an accidental entry of something that doesn't begin with a digit)
Example Use/Output
$ ./bin/int2bin
enter a integer value: 0
binary: 0
$ ./bin/int2bin
enter a integer value: 2
binary: 10
$ ./bin/int2bin
enter a integer value: 15
binary: 1111
Two's-complement of negative values:
$ ./bin/int2bin
enter a integer value: -15
binary: 11111111111111111111111111110001
Look things over and let me know if you have any questions, or if you really need bin to be an array of int. Having an integer array holding the individual bit values doesn't make a whole lot of sense, but if that is what you have to do, I'm happy to help.

Check bit value at particular position in a binary with C language

I don't know why, I tried all the implementations I've found here in stack, but every of them have this strange behaviour.
My aim is: given a decimal, change it to binary and retrieve a bit at given position value.
Let's say I got this binary, which is decimal 255:
11111111
Well using this:
#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))//other test
#define NCHECK_BIT(int, pos) (!! int & (1 << pos))
unsigned char* REG_SW ;
//from int to binary
unsigned int int_to_int(unsigned int k) {
return (k == 0 || k == 1 ? k : ((k % 2) + 10 * int_to_int(k / 2)));
}
int checkBitPosition(){
REG_SW = (unsigned char*) 0x300111;
return NCHECK_BIT(int_to_int(REG_SW [0]),6)==false?1:0 ;
}
it returns me true if the bit is 0 at sixth but also second (and some others..actually!!) so the results are impredictable... I didn't get the logic behind that gives me the result.
I assume that the int to binary translator works well, 'cause I'm printing that and it's always the correct binary taken from the int I give.
Can anybody help me?
Thanks in advance!
You are converting a number into its binary format first and then you are checking that binary format with your macros. This is wrong, since your macros will check for the position of the bit in the resulting number (not your original number) i.e,
first your number = 10 and binary format is 1010
now to check the bits you have to pass 10 as argument for your macros and not 1010
if you pass the binary representation 1010 to the macro then binary representation of the number 1010 will be checked for pos and not for 10.

Integer range and Overflow

This is a simple program to convert positive decimal number into binary. I have to report and stop conversion of those numbers which could cause overflow or erroneous results. I found size of integer is 4 Bytes but it converts correctly upto 1023 only.
I am confuse where the number "1023" came from? Is there any method to calculate so i can predict what will be the correct range, if say, i am programming on another system.
#include<stdio.h>
int main(void)
{
int decimal,binary=0,y,m=1;
scanf("%d",&decimal);
if(decimal<=1023)
{
while(decimal>0)
{
y=decimal%2;
binary=binary+(m*y);
m=m*10;
decimal=decimal/2;
}
printf("\nBinary Equivalent is: %d",binary);
}
else
{printf("Sorry, The Number You've entered exceeds the maximum allowable range for conversion");}
getch();
return 0;
}
1023 is equal to 1024-1 (2^10 -1), so a number lesser than or equal to 1023 will have 10 digits in base 2. Since you are using an int to get the result, it stores up to 2^31-1 = 2147483647 (31 because one of the 32 bits is used to represent the sign (+ or -)). When you have a 1024 or higher number, it uses more than 10 digits - and, thus, is higher than 2147483647.
Hope that helps.
Actually, the range of an integer is between [-2^31, 2^31-1]. Because there are 4 bytes (i.e., 32 bits). However, if you want to scanf a non-negative integer. you have to initial a unsigned int rather int. The range will be [0, 2^32-1].
The problem is in the temporary variables binary and m you use. Because 1024 would take 11 divisions to become 0, m will become 10.000.000.000. However, the maximum value of an int is 2.147.483.647 (since one bit of the four bytes is used as a sign bit). m will thus overflow, which results in an incorrect result. 1023 or smaller values will take 10 devisions or less to become 0, so m is max 1.000.000.000, so m has no overflow.
You seem to want to take a 4 byte decimal number and convert it to a binary string of 0s and 1s. The method used in the code fails when the decimal number is > 1023. Here is a conversion that produces a string of 0s and 1s that can be printed using:
printf("\nBinary Equivalent is: ");
while( int i = 0; i < 32; i++ )
{
printf( "%c", (decimal & (1<<i) )? '1': '0');
}
printf("\n");
This eliminates much of the code clutter and produces the desired output.

Resources