Decimal to binary in C language - c

I wrote simple code in C language (without libraries), but the result is good only when you read it from right to left, how to reverse it? I want the most simplified code as it is possible. My code below:
#include <stdio.h>
int main() {
int number;
printf("Changes from decimal to binary\n");
printf("Enter the number: ");
scanf("%d",&number);
do{
if(number % 2 == 1){
printf("1");
}else{
printf("0");
}
number = number / 2;
}
while(number>0);
return 0;
}

You could store the binary number in an array and then print it backwards. So you would have for example int binaryDigits[1024]; and then instead of printing you will store the number in the array with a counter. Before the loop: int i = 0; and after that instead of printf("1"); and printf("0");, binaryDigits[i++] = 1 and binaryDigits[i++] = 0 respectively. Finally you could print the number in order with a for loop:
for (i = i - 1; i >= 0; i--)
printf("%d", binaryDigits[i])

You could use recursion and print the digits as you fall off the stack. I changed number from int to unsigned int.
void print_dec_to_bin_hlp(unsigned int number)
{
if(number > 0)
{
print_dec_to_bin_hlp(number/2);
printf("%d", (number%2));
}
}
void print_dec_to_bin(unsigned int number)
{
if (number == 0) printf("%d", number);
else print_dec_to_bin_hlp(number);
}

A recursive solution using bitwise operations, for unsigned integers:
void print_binary(unsigned int num) {
if(num >> 1) print_binary(num >> 1);
putchar(num & 1 ? '1' : '0');
}
The bitwise operators >>, &, etc. access the bits in the value. The bits form a binary representation of the number. >> shifts the bits to the right, where the bits are ordered from MSB (most significant bit) to LSB, like the normal way numbers are written.
num & 1 returns non-zero only if the LSB (rightmost) bit is set. (AND mask with ..0001). So (num >> 1) & 1 does the same on the second-rightmost bit. So this recursive function prints the bits in MSB to LSB order.
The if(num >> 1) check makes sure prefix zeroes are not printed: If after the rightshift, num is all-zeroes, it is not printed any further. The check is made outside the function call, so that print_binary(0) (initial call) will still always print a single 0.
For signed integers:
void print_signed_binary(int num) {
if(num < 0) {
putchar('-');
print_binary(-num);
} else {
print_binary(num);
}
}

Related

C integer to binary bit order

Below C program display binary representation of inputted decimal number:
#include <stdio.h>
#include <stdlib.h>
typedef union {
int i;
struct {
unsigned int dgts: 31;
unsigned int sign: 1;
} bin;
} myint;
void printb(int n, int i) {
int k;
for (k = i - 1; k >= 0; k--)
if ((n >> k) & 1)
printf("1");
else
printf("0");
}
void display_binary(myint x) {
printf("%d | ", x.bin.sign);
printb(x.bin.dgts, 31);
printf("\n");
}
int main() {
myint decimal;
printf("input decimal value : ");
scanf("%d", &decimal.i);
printf("Binary representation is:\n");
display_binary(decimal);
return 0;
}
The program is working correctly. What I can't understand is order of dgts and sign members of bin struct. Intuitively, sign member should precede dgts as bits that representing data are ordered from left to write in memory (as far as I know). After swapping orders of these two members, result became false. Why dgts should come before sign?
order of bits in the bitfields is implementation-defined, but most popular compilers start with LSB.
Numbers are stored binary and it does not matter how you enter them. Negative numbers are stored as two'2 complement on most modern systems. In this system, the sign bit does not exist "per se". No special types are needed
I would implement it as
void printb(int n) {
unsigned int mask = 1U << (sizeof(n) * CHAR_BIT - 1);
for (; mask; mask >>= 1)
{
printf("%c", (n & mask) ? '1' : '0');
}
}

Binary two consecutive 1 bits

I am trying to implement with C that outputs the number of two consecutive 1-bits in an integer without overlapping. This is my code:
#include <stdio.h>
int numPairs(int num) {
int count = 0;
while (num) {
num = (num & (num << 1));
count++;
}
return count / 2;
}
int main(){
printf("%d\t", numPairs(10000));
printf("%d\t", numPairs(146));
printf("%d\t", numPairs(7645));
printf("%d\t", numPairs(16383));
return 0;
}
My output is 1 0 1 7
But the output should be 1 0 3 7
Everything is correct except for 7645, and I don't know what is wrong with this.
For 7645 my code gives the result 1 but the correct result is 3.
Your method is inappropriate:
You count the number of iterations required to null the expression n = n & (n << 1);. This will would be the maximum number of consecutive 1 bits. If the bit pairs are separate, the result will be different from the number of non overlapping bit pairs.
In the case in 7645, 0x1ddd or 0001 1101 1101 1101 in decimal, there are 3 groups of 3 consecutive 1 bits, but they get nulled in parallel 3 iterations of the loop, hence count / 2 is 1.
You must use a different algorithm such as:
int numPairs(int num) {
int count = 0;
unsigned int x = num;
while (x) {
if ((x & 3) == 3) {
count++;
x >>= 2;
} else {
x >>= 1;
}
}
return count;
}
In case speed is important, this can also be done with bit manipulation operations:
int numPairs(uint32_t x) {
return __builtin_popcount((((x ^ 0x55555555) + 0x55555555) ^ 0x55555555) & x);
}
This produces a 1 bit in the upper bit of each disjoint 2-bit group of ones, and then counts the 1 bits.

Convert Decimal Number to char array of it's binary representation:

How would I write code in C to assign a decimal number's binary representation to a char variable?
\\ x is the value of the decimal integer
\\ y is length of the binary representation
{
binary[33] = {0};
while(x!=0){
binary[y] = (x%2)+'0';
y--;
x/=2;
}
}
The idea of scanning bits in number is to start with MSB bit of input number and to proceed to the LSB bit. When first 1 is detected, start printing/saving/whatever, even if 0 is later detected.
This is now example, which will print bits of your number, starting to print when it reaches first 1.
#include <stdio.h>
#include "limits.h"
int main() {
unsigned int num = 10;
int y = 0, i;
for (i = sizeof(num) * CHAR_BIT - 1; i >= 0; i--) {
if (num & (1U << i)) {
printf("1");
y++;
} else if (y) {
printf("0");
y++;
}
}
printf("\n");
return 0;
}
Output for num = 10: 1010
If you want to store your result to array, replace printf statements with something similar to: outputBuffer[y] = '1' or '0'

how can i convert hexadecimal number to binary using bit-mask

int main()
{
double hexa_number;
double bitmask = 0x80;
double i;
printf("Enter 8 bit number in hexadecimal form: ");
scanf("%lf",& hexa_number);
for( i = 0; i <= 8; i++)
{
if(hexa_number&(bitmask >> i))
printf("1");
else
printf("0");
}
return 0;
}
plus Displaying the binary representation of this number,
along with a count of the number of 0’s and 1’s in the binary number.
i found other ways to convert it but not with bitmask
The problem could be that you are using a double for your bitmask. I don't think >> makes much sense for doubles especially as they are composed of a sign bit, mantissa and 2^ exponent.
For example, 8 >> 1 is 4. That is a nice consistent operation, same as division by 2.
If we imagine an unsigned two byte float for simplicity and imagine that the first byte represents the mantissa and the second the exponent (both unsigned), then 7 * 2^4 (=112) could be represented as 0b00000111 00000100. If you shift that 1 to the right, >> 1, you will get 0b00000011 10000010, which by our convention is now 3 * 2^130. This is definitely not the division by 2 you would get by shifting an integer right by 1.
My compiler gives "error: invalid operands to binary >> (have double and unsigned)" if I try bitwise shifting a floating point number.
So basically you could try the following:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int hexa_number = 0;
unsigned num_bits = sizeof(int)*8;
unsigned bitmask = 1 << (num_bits - 1);
printf("Enter a number in hexadecimal form: ");
scanf("%i", &hexa_number);
unsigned k = 0;
unsigned num_ones = 0;
unsigned num_zeros = 0;
for(k = 0; k != num_bits; k ++)
{
if(hexa_number & (bitmask >> k))
{
printf("1");
num_ones ++;
}
else
{
printf("0");
num_zeros++;
}
}
printf("\nNumber of ones is %i\nNumber of zeros is %i", num_ones, num_zeros);
return 0;
}

Setting Parity Bit in a Transmission Program

I am writing a program that simulate a transmission of characters over the network.
I have written the following function:
int getCharBit(char c, int bitNum){
return (c & (1 <<bitNum)) >> bitNum;
}
// returns the ith bit of the character c
int getShortBit(short num, int bitNum)
{
return (num & (1 <<bitNum)) >> bitNum;
}
// sets bit i in num to 1
int setShortBit(int bitNum, short *num){
return num | (1 << bitNum);
}
// count the number of bits in the short and returns the number of bits
/* input:
num - an integer
Output:
the number of bits in num
*/
int countBits(short num)
{
int sum=0;
int i;
for(i = num; i != 0; i = i >> 1){
sum += i & 1;
}
return sum;
}
I also written a function that counts the number of ones in a short integer num and a mask:
int countOnes(short int num, short int pMask){
short tempBit = num & pMask;
sum = 0;
while(tempBit > 0){
if((tempBit & 1) == 1){
sum ++;
}
tempBit >> 1;
}
return sum;
}
and a function that sets the Parity Bit:
int setParityBits(short *num)
// set parity bit p1 using mask P1_MASK by
// get the number of bits in *num and the mask P1_MASK
int numOnes = countOnes(num, P1_MASK);
// if the number of bits is odd then set the corresponding parity bit to 1 (even parity)
if ((numOnes % 2) != 0){
setShortBit(1, num);
}
// do the same for parity bits in positions 2,4,8
int numOnes2 = countOnes(num, P2_MASK);
if ((numOnes2 % 2) != 0){
setShortBit(2, num);
}
int numOnes4 = countOnes(num, P4_MASK);
if ((numOnes4 % 2) != 0){
setShortBit(4, num);
}
int numOnes8 = countOnes(num, P8_MASK);
if ((numOnes8 % 2) != 0){
setShortBit(8, num);
}
I am also given a few function that are supposed to read the input and transmit it. The problem is in one of the functions I have written.
For example, if I run the program and type hello as an input, I should get 3220 3160 3264 3264 7420 as an output, but I get 0 0 0 0 0.
I can't seem to find what I was doing wrong, Could someone please help me?

Resources