Decimal to binary conversion (8 bit) in C - c

I've been working on an assignment and so far this is what i've gotten.
int n, c;
printf("Enter a decimal\n");
scanf_s("%d", &n);
printf("%d in binary is: ", n);
for (c = 7; c >= 0; c--)
{
if (n >= 1)
printf("1");
n = n - 1;
else (n < 1)
printf("0");
n = n / 2;
}
I'm new to code and am struggling to figure out where to go from here. Any help would be greatly appreciated.

void printbin(unsigned char val)
{
for(unsigned char i = 0x80; i; i >>= 1)
printf("%c", val & i ? '1' : '0');
printf("\n");
}

Use a bitmask to test if a bit is set. To construct a bitmask one could use bit-shifting:
1 << 0 // shift 1 0 bits to the left: 0b00000001
1 << 1 // shift 1 0 bits to the left: 0b00000010
1 << 2 // shift 1 0 bits to the left: 0b00000100
1 << 3 // shift 1 0 bits to the left: 0b00001000
1 << 4 // shift 1 0 bits to the left: 0b00010000
1 << 5 // shift 1 0 bits to the left: 0b00100000
1 << 6 // shift 1 0 bits to the left: 0b01000000
1 << 7 // shift 1 0 bits to the left: 0b10000000
Then you can use that values to test if a specific bit is set using the bitwise-and operator:
value & (1 << 4) // evaluates to true if bit 5 is set.
// counted 1-based from the right.
To use that to output a 8-bit value:
char unsigned value = 42; // an 8-bit value
for (int bit = 8; bit; --bit) { // count from 8 to 1
putchar(value & (1 << (bit - 1)) ? '1' : '0');
}

First of all you need to know that for conversion from decimal to binary we divide the decimal number repeatedly by 2 and store the reminder and multiply it with the place value so for that we will initialize three variables rem(for storing the reminder) bin(for updating the binary value) place( for getting the place value)
Here is the code for converting decimal to binary value
#include<stdio.h>
#include<string.h>
#include<math.h>
int main()
{
int num,bin=0,place=1,rem;
printf("Enter the number\n");
scanf("%d",&num);
while(num>0)
{
rem =num%2; //Returns the reminder by dividing the number with 2
num =num/2; //Returns the integer value after dividing the number by 2
bin += place*rem; //Store the binary value
place *= 10;
}
printf("The binary number is %d",bin);
}

Related

How do I get the digit from my input and print it out?

I'm trying to make a program that converts octal numbers into regular integers. My code looks like this.
#include <stdio.h>
int main(void) {
unsigned int c, num = 0, ct = 0;
printf("Please input a positive octal integer and end with pressing Enter:\n");
// Read the octal string, at most 10 characters.
while ((c = getchar()) != '\n' && ((c >= '0' && c <= '9') && ct++ < 11)) {
// Convert the input string to an value storing in int
num = num << 3 | (c - '0');
}
// If the input is not valid, output the error message.
if (c != '\n') {
printf("ERROR: the input should be an octal string containing 0-7, with length less than 11!\n");
} else { // Output the conversion table.
printf("i\t8^i\tdigit\tproduct\n");
for (int i = 0; i < ct; i++) {
printf("%u\t%u\t%u\t%u\n",
i, // Position i
1 << (3 * i), // Get 8 ** i
num >> (3 * i) & 7, // Get bit at position i
(1 << (3 * i)) * (num >> (3 & i) & 7)); // Multiply 8 ** i to the bit at position i
}
// Output the decimal value
printf("Decimal value: %d\n", num);
}
return 0;
}
The result should be this:
Please input a positive octal integer and end with pressing Enter:
7326
i 8^i digit product
0 1 6 6
1 8 2 16
2 64 3 192
3 512 7 3584
Decimal value: 3798
But instead it looks like this:
Please input a positive octal integer and end with pressing Enter:
7326
i 8^i digit product
0 1 6 6
1 8 2 24
2 64 3 320
3 512 7 1024
Decimal value: 3798
I believe the problem lies in line 32-33:
num >> (3 * i) & 7, // Get bit at position i
(1 << (3 * i)) * (num >> (3 & i) & 7)); // Multiply 8 ** i to the bit at position i
But I don't know how to solve the problem specifically.
The last arg of the printf : * (num >> (3 * i) & 7) needs to be * (num >> (3 * i) & 7) (*, not &)
printf("%u\t%u\t%u\t%u\n",
i, // Position i
1 << (3 * i), // Get 8 ** i
num >> (3 * i) & 7, // Get bit at position i
(1 << (3 * i)) * (num >> (3 * i) & 7)); // Multiply 8 ** i to the bit at position i
}
This yields your expected result.

Reversing the nibbles

I am trying to "build a new number by reversing its nibbles".
This is the exercise:
Write a function that given an unsigned n
a) returns the value with the nibbles placed in reverse order
I was thinking that all the 8 nibbles from the 32 bit unsigned should be placed in reverse order. So , as an example for the number 24, which is 00000000000000000000000000011000.
=> The reversed value should be: 10000001000000000000000000000000.
#include <stdio.h>
unsigned getNibble(unsigned n,unsigned p){
unsigned mask = 0xFu;
unsigned nibble = 0;
nibble = (n&(mask<<p))>>p;
return nibble;
}
unsigned swapNibbles(unsigned n){
unsigned new = 0;
unsigned nibble;
for(unsigned i=0;i<(sizeof(n)*8);i=i+4){
nibble = getNibble(n,i);
new = (new<<i) + nibble;
}
return new;
}
int main(void) {
printf("0x%x",swapNibbles(24));
return 0;
}
I tried to debug it , and it went well until one point.
At one of the right shifts , it transformed my "new" variable into 0.
This statement
new = (new << i) + nibble;
is wrong. There should be
new = (new << 4) + nibble;
An approach that does work in parallel:
uint32_t n = ...;
// Swap the nibbles of each byte.
n = (n & 0x0F0F0F0F ) << 4
| (n & 0xF0F0F0F0 ) >> 4;
// Swap the bytes of each byte pair.
n = ( n & 0x00FF00FF ) << 8
| ( n & 0xFF00FF00 ) >> 8;
// Swap the byte pairs.
n = ( n & 0x0000FFFF ) << 16
| ( n & 0xFFFF0000 ) >> 16;
Doing the work in parallel greatly reduces the number of operations.
OP's This
Approach Approach
-------- --------- ---------
Shifts 24 / 48 6 / 8 32 bits / 64 bits
Ands 8 / 16 6 / 8
Ors* 8 / 16 3 / 4
Assigns 8 / 16 3 / 4
Adds 8 / 16 0 / 0
Compares 8 / 16 0 / 0
-------- --------- ---------
Total 64 / 128 18 / 24
-------- --------- ---------
Scale O(N) O(log(N))
* Addition was used as "or" in the OP's solution.
int main (void)
{
uint32_t x = 0xDEADBEEF;
printf("original 4 bytes %X\n", x);
uint32_t y = 0;
for(uint8_t i = 0 ; i < 32 ; i += 4)
{
y <<= 4;
y |= x>>i & 0xF;
}
printf("reverse order nibbles %X\n", y);
return 0;
}
This could be made generic function for accepting all 8,16,32 bits numbers. But for now this resolves the bug you are facing in your code.
But I would point out ikegami's code is much better than this approach.

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.

Extracting a particular range of bits and find number of zeros between them in C

I want to extract a particular range of bits in an integer variable.
For example: 0xA5 (10100101)
I want to extract from bit2 to bit5. i.e 1001 to a variable and count number of zeros between them.
I have another variable which give the starting point, which means in this case the value of the variable is 2. So the starting point can be find by 0xA5 >> 2.
5th bit position is a random position here..means it can be 6 or 7. The main idea is whichever bit is set to 1 after 2nd bit. I have to extract that..
How can I do rest of the part ?
Assuming you are dealing with unsigned int for your variable.
You will have to construct the appropriate mask.
Suppose you want the bits from position x to position y, there need to be y - x + 1 1s in the mask.
You can get this by -
int digits = y - x + 1;
unsigned int mask = 1u << digits - 1;
Now you need to remove the lower x bits from the initial number, which be done by -
unsigned int result = number >> x;
Finally apply the mask to remove the upper bits -
result = result & mask;
In this example we put 0 or 1 values into array. After that you can treat array as you like.
#include <stdio.h>
#include <stdint.h>
int main(int argc, char **argv) {
uint8_t value = 0xA5;
unsigned char bytes[8];
unsigned char i;
for (i = 0; i < 8; i++) {
bytes[i] = (value & (1 << i)) != 0 ? 1 : 0;
}
for (i = 0; i < 8; i++) {
printf("%d", bytes[i]);
}
return 0;
}
You could use a mask and the "&" (AND) operation:
a = 0xA5;
a = a >> OFFSET; //OFFSET
mask = 0x0F; // equals 00001111
a = a & mask;
In your example a = 0xA5 (10100101), and the offset is 2.
a >> 2 a now equals to 0x29 (00101001)
a & 0x0F (00101001 AND
00001111) = 00001001 = 0x09
If you want bits from the offset X then shift right by X.
If you want Y bits, then then mask (after the shift) will be 2 to the power of Y minus one (for your example with four bits, 2 to the power of 4 is 16, minus one is 15 which is 1111 binary). This can be dome by using left-shifting by Y bits and subtracting 1.
However, the masking isn't needed if you want to count the number of zeros in the wanted bits, only the right shift. Loop Y times, each time shifting a 1 left one step, and check using bitwise and if the value is zero. If it is then increment a counter. At the end of the loop the counter is the number of zeros.
To put it all in code:
// Count the number of zeros in a specific amount of bits starting at a specific offset
// value is the original value
// offset is the offset in bits
// bits is the number of bits to check
unsigned int count_zeros(unsigned int value, unsigned int offset, unsigned int bits)
{
// Get the bits we're interested in the rightmost position
value >>= offset;
unsigned int counter = 0; // Zero-counter
for (unsigned int i = 0; i < bits; ++i)
{
if ((value & (1 << i)) == 0)
{
++counter; // Bit is a zero
}
}
return counter;
}
To use with the example data you have:
count_zeros(0xa5, 2, 4);
The result should be 2. Which it is if you see this live program.
int32_t do_test(int32_t value, int32_t offset)
{
int32_t _zeros = 1;
value >>= offset;
int i = 1;
while(1) {
if((value >> i) % 2 == 0) {
_zeros += 1;
i++;
} else {
break;
}
}
}
int result = (0xA5 >> 2) & 0x0F;
Truth table for the & operator
| INPUTS | OUTPUT |
-----------------------
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
-----------------------

Bitwise operations equivalent of greater than operator

I am working on a function that will essentially see which of two ints is larger. The parameters that are passed are 2 32-bit ints. The trick is the only operators allowed are ! ~ | & << >> ^ (no casting, other data types besides signed int, *, /, -, etc..).
My idea so far is to ^ the two binaries together to see all the positions of the 1 values that they don't share. What I want to do is then take that value and isolate the 1 farthest to the left. Then see of which of them has that value in it. That value then will be the larger.
(Say we use 8-bit ints instead of 32-bit).
If the two values passed were 01011011 and 01101001
I used ^ on them to get 00100010.
I then want to make it 00100000 in other words 01xxxxxx -> 01000000
Then & it with the first number
!! the result and return it.
If it is 1, then the first # is larger.
Any thoughts on how to 01xxxxxx -> 01000000 or anything else to help?
Forgot to note: no ifs, whiles, fors etc...
Here's a loop-free version which compares unsigned integers in O(lg b) operations where b is the word size of the machine. Note the OP states no other data types than signed int, so it seems likely the top part of this answer does not meet the OP's specifications. (Spoiler version as at the bottom.)
Note that the behavior we want to capture is when the most significant bit mismatch is 1 for a and 0 for b. Another way of thinking about this is any bit in a being larger than the corresponding bit in b means a is greater than b, so long as there wasn't an earlier bit in a that was less than the corresponding bit in b.
To that end, we compute all the bits in a greater than the corresponding bits in b, and likewise compute all the bits in a less than the corresponding bits in b. We now want to mask out all the 'greater than' bits that are below any 'less than' bits, so we take all the 'less than' bits and smear them all to the right making a mask: the most significant bit set all the way down to the least significant bit are now 1.
Now all we have to do is remove the 'greater than' bits set by using simple bit masking logic.
The resulting value is 0 if a <= b and nonzero if a > b. If we want it to be 1 in the latter case we can do a similar smearing trick and just take a look at the least significant bit.
#include <stdio.h>
// Works for unsigned ints.
// Scroll down to the "actual algorithm" to see the interesting code.
// Utility function for displaying binary representation of an unsigned integer
void printBin(unsigned int x) {
for (int i = 31; i >= 0; i--) printf("%i", (x >> i) & 1);
printf("\n");
}
// Utility function to print out a separator
void printSep() {
for (int i = 31; i>= 0; i--) printf("-");
printf("\n");
}
int main()
{
while (1)
{
unsigned int a, b;
printf("Enter two unsigned integers separated by spaces: ");
scanf("%u %u", &a, &b);
getchar();
printBin(a);
printBin(b);
printSep();
/************ The actual algorithm starts here ************/
// These are all the bits in a that are less than their corresponding bits in b.
unsigned int ltb = ~a & b;
// These are all the bits in a that are greater than their corresponding bits in b.
unsigned int gtb = a & ~b;
ltb |= ltb >> 1;
ltb |= ltb >> 2;
ltb |= ltb >> 4;
ltb |= ltb >> 8;
ltb |= ltb >> 16;
// Nonzero if a > b
// Zero if a <= b
unsigned int isGt = gtb & ~ltb;
// If you want to make this exactly '1' when nonzero do this part:
isGt |= isGt >> 1;
isGt |= isGt >> 2;
isGt |= isGt >> 4;
isGt |= isGt >> 8;
isGt |= isGt >> 16;
isGt &= 1;
/************ The actual algorithm ends here ************/
// Print out the results.
printBin(ltb); // Debug info
printBin(gtb); // Debug info
printSep();
printBin(isGt); // The actual result
}
}
Note: This should work for signed integers as well if you flip the top bit on both of the inputs, e.g. a ^= 0x80000000.
Spoiler
If you want an answer that meets all of the requirements (including 25 operators or less):
int isGt(int a, int b)
{
int diff = a ^ b;
diff |= diff >> 1;
diff |= diff >> 2;
diff |= diff >> 4;
diff |= diff >> 8;
diff |= diff >> 16;
diff &= ~(diff >> 1) | 0x80000000;
diff &= (a ^ 0x80000000) & (b ^ 0x7fffffff);
return !!diff;
}
I'll leave explaining why it works up to you.
To convert 001xxxxx to 00100000, you first execute:
x |= x >> 4;
x |= x >> 2;
x |= x >> 1;
(this is for 8 bits; to extend it to 32, add shifts by 8 and 16 at the start of the sequence).
This leaves us with 00111111 (this technique is sometimes called "bit-smearing"). We can then chop off all but the first 1 bit:
x ^= x >> 1;
leaving us with 00100000.
An unsigned variant given that one can use logical (&&, ||) and comparison (!=, ==).
int u_isgt(unsigned int a, unsigned int b)
{
return a != b && ( /* If a == b then a !> b and a !< b. */
b == 0 || /* Else if b == 0 a has to be > b (as a != 0). */
(a / b) /* Else divide; integer division always truncate */
); /* towards zero. Giving 0 if a < b. */
}
!= and == can easily be eliminated., i.e.:
int u_isgt(unsigned int a, unsigned int b)
{
return a ^ b && (
!(b ^ 0) ||
(a / b)
);
}
For signed one could then expand to something like:
int isgt(int a, int b)
{
return
(a != b) &&
(
(!(0x80000000 & a) && 0x80000000 & b) || /* if a >= 0 && b < 0 */
(!(0x80000000 & a) && b == 0) ||
/* Two more lines, can add them if you like, but as it is homework
* I'll leave it up to you to decide.
* Hint: check on "both negative" and "both not negative". */
)
;
}
Can be more compact / eliminate ops. (at least one) but put it like this for clarity.
Instead of 0x80000000 one could say ie:
#include <limits.h>
static const int INT_NEG = (1 << ((sizeof(int) * CHAR_BIT) - 1));
Using this to test:
void test_isgt(int a, int b)
{
fprintf(stdout,
"%11d > %11d = %d : %d %s\n",
a, b,
isgt(a, b), (a > b),
isgt(a, b) != (a>b) ? "BAD!" : "OK!");
}
Result:
33 > 0 = 1 : 1 OK!
-33 > 0 = 0 : 0 OK!
0 > 33 = 0 : 0 OK!
0 > -33 = 1 : 1 OK!
0 > 0 = 0 : 0 OK!
33 > 33 = 0 : 0 OK!
-33 > -33 = 0 : 0 OK!
-5 > -33 = 1 : 1 OK!
-33 > -5 = 0 : 0 OK!
-2147483647 > 2147483647 = 0 : 0 OK!
2147483647 > -2147483647 = 1 : 1 OK!
2147483647 > 2147483647 = 0 : 0 OK!
2147483647 > 0 = 1 : 1 OK!
0 > 2147483647 = 0 : 0 OK!
A fully branchless version of Kaganar's smaller isGt function might look like so:
int isGt(int a, int b)
{
int diff = a ^ b;
diff |= diff >> 1;
diff |= diff >> 2;
diff |= diff >> 4;
diff |= diff >> 8;
diff |= diff >> 16;
//1+ on GT, 0 otherwise.
diff &= ~(diff >> 1) | 0x80000000;
diff &= (a ^ 0x80000000) & (b ^ 0x7fffffff);
//flatten back to range of 0 or 1.
diff |= diff >> 1;
diff |= diff >> 2;
diff |= diff >> 4;
diff |= diff >> 8;
diff |= diff >> 16;
diff &= 1;
return diff;
}
This clocks in at around 60 instructions for the actual computation (MSVC 2010 compiler, on an x86 arch), plus an extra 10 stack ops or so for the function's prolog/epilog.
EDIT:
Okay, there were some issues with the code, but I revised it and the following works.
This auxiliary function compares the numbers' n'th significant digit:
int compare ( int a, int b, int n )
{
int digit = (0x1 << n-1);
if ( (a & digit) && (b & digit) )
return 0; //the digit is the same
if ( (a & digit) && !(b & digit) )
return 1; //a is greater than b
if ( !(a & digit) && (b & digit) )
return -1; //b is greater than a
}
The following should recursively return the larger number:
int larger ( int a, int b )
{
for ( int i = 8*sizeof(a) - 1 ; i >= 0 ; i-- )
{
if ( int k = compare ( a, b, i ) )
{
return (k == 1) ? a : b;
}
}
return 0; //equal
}
As much as I don't want to do someone else's homework I couldn't resist this one.. :) I am sure others can think of a more compact one..but here is mine..works well, including negative numbers..
Edit: there are couple of bugs though. I will leave it to the OP to find it and fix it.
#include<unistd.h>
#include<stdio.h>
int a, b, i, ma, mb, a_neg, b_neg, stop;
int flipnum(int *num, int *is_neg) {
*num = ~(*num) + 1;
*is_neg = 1;
return 0;
}
int print_num1() {
return ((a_neg && printf("bigger number %d\n", mb)) ||
printf("bigger number %d\n", ma));
}
int print_num2() {
return ((b_neg && printf("bigger number %d\n", ma)) ||
printf("bigger number %d\n", mb));
}
int check_num1(int j) {
return ((a & j) && print_num1());
}
int check_num2(int j) {
return ((b & j) && print_num2());
}
int recursive_check (int j) {
((a & j) ^ (b & j)) && (check_num1(j) || check_num2(j)) && (stop = 1, j = 0);
return(!stop && (j = j >> 1) && recursive_check(j));
}
int main() {
int j;
scanf("%d%d", &a, &b);
ma = a; mb = b;
i = (sizeof (int) * 8) - 1;
j = 1 << i;
((a & j) && flipnum(&a, &a_neg));
((b & j) && flipnum(&b, &b_neg));
j = 1 << (i - 1);
recursive_check(j);
(!stop && printf("numbers are same..\n"));
}
I think I have a solution with 3 operations:
Add one to the first number, the subtract it from the largest possible number you can represent (all 1's). Add that number to the second number. If it it overflows, then the first number is less than the second.
I'm not 100% sure if this is correct. That is you might not need to add 1, and I don't know if it's possible to check for overflow (if not then just reserve the last bit and test if it's 1 at the end.)
EDIT: The constraints make the simple approach at the bottom invalid. I am adding the binary search function and the final comparison to detect the greater value:
unsigned long greater(unsigned long a, unsigned long b) {
unsigned long x = a;
unsigned long y = b;
unsigned long t = a ^ b;
if (t & 0xFFFF0000) {
x >>= 16;
y >>= 16;
t >>= 16;
}
if (t & 0xFF00) {
x >>= 8;
y >>= 8;
t >>= 8;
}
if (t & 0xf0) {
x >>= 4;
y >>= 4;
t >>= 4;
}
if ( t & 0xc) {
x >>= 2;
y >>= 2;
t >>= 2;
}
if ( t & 0x2) {
x >>= 1;
y >>= 1;
t >>= 1;
}
return (x & 1) ? a : b;
}
The idea is to start off with the most significant half of the word we are interested in and see if there are any set bits in there. If there are, then we don't need the least significant half, so we shift the unwanted bits away. If not, we do nothing (the half is zero anyway, so it won't get in the way). Since we cannot keep track of the shifted amount (it would require addition), we also shift the original values so that we can do the final and to determine the larger number. We repeat this process with half the size of the previous mask until we collapse the interesting bits into bit position 0.
I didn't add the equal case in here on purpose.
Old answer:
The simplest method is probably the best for a homework. Once you've got the mismatching bit value, you start off with another mask at 0x80000000 (or whatever suitable max bit position for your word size), and keep right shifting this until you hit a bit that is set in your mismatch value. If your right shift ends up with 0, then the mismatch value is 0.
I assume you already know the final step required to determine the larger number.

Resources