Unsigned Short Division for binary representation in C - c

So I am trying to do an integer division on a binary representation of an unsigned short. For example: Say the Unsigned Short x=5, the binary number representation is
1111. 7 would be 111. I want to be able to find the number of Pairs of the 1's bit representation. My idea was to count the number of 1's using bit manipulation as follows.
unsigned short divide(unsigned short input) {
unsigned short count = 0;
while (input != 0){
if ((input & 1) == 1)
count = count + 1;
input = input >> 1;
}
return count;
}
The above code works for getting the total number of 1 bits in a binary representation. Example: in my 7, it would return 3 since there are 3 1's in the binary representation. Now I just want to be able to perform integer division such as 3/2=1 to find the number of 1 pairs. 3/2 for an unsigned short would be 1 since there are only 1 pair of 1's bits. if for 5, it would be 4/2=2. 2 pairs. How would I go about in terms of implementing a integer division without using arithmetic operations such as modulus, +,-,*,/.

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'.

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

Depiction of binary digit changes during promotion from signed to unsigned integers/what happens?

y is promoted to unsigned int and compared with x here.Does binary number comparison happen everytime? Then if(12 == -4) is done, why can't it promote LHS to unsigned and print "same"?(considering 12 = 1100, -4 = 1100)Please correct if I am wrong.
#include<stdio.h>
int main()
{
unsigned int x = -1;
int y = ~0;
if(x == y)//1.what happens if( y == x) is given?.O/P is "same" then also.
printf("same");//output is "same"
else
printf("not same");
printf("%d",x);//2.output is -1.Won't x lose it's sign when unsigned is given?My hunch is x should become +1 here.
getchar();
return 0;
}
Please also provide the binary number working for the above code and answers to 1. and 2. in the code comments.Thank you.
First check in your system for size of unsigned int.
in my machine: printf("%zu\n",sizeof(unsigned int));//4 byte
as we have 4 bytes to store an Uint data type, we can say
unsigned int x ;//
x:Range[0, Max_number_with_4byte]
Max_number_with_4byte: (2^32) - 1 = 0xFFFFFFFF
obviously x can hold only positive numbers because of unsigned.
but you give to x = -1;, suppose a circular behaviour, when we put back one step from 0, x reach to last point: Max_number_with_4byte.
and printing x to screen shows: 0xFFFFFFFF
see hex equivalent of x with printf("%x\n",(unsigned int )x);
and printf("%y\n",(unsigned int )y); to see equality of x,y.
consider y = ~0; we have 32 bits for y if ~ operator use in y all bits are changes to 1, in hex form we see FFFFFFFF. (we cant print binary numbers with printf and use equal hex representation)
you can see this online calculator how to convert -1 to 0xFFFFFFFF
Answer to your Question
y is not promoted to unsigned int. it is just changes its bits form 0 -> 1
Does binary number comparison happen every time?
Yes in every conditions for example in if(10 > 20) first both 10 and 20 converted to its correspondent binary numbers then compare.
if (12 == -4) see my above explanation.
-4 not equals to 1100 inside computer (your variable).
-4 = 0xFFFFFFFC see
An unsigned int =-1 should actually interpreted as the max unsigned int(4294967295); surely is not transformed into 1.

Hex remove leading digits

When you do something like 0x01AE1 - 0x01AEA = fffffff7. I only want the last 3 digits. So I used the modulus trick to remove the extra digits. The displacement gets filled with hex values.
int extra_crap = 0;
int extra_crap1 = 0;
int displacement = 0;
int val1 = 0;
int val2 = 0;
displacement val1 - val2;
extra_crap = displacement % 0x100;
extra_crap1 = displacement % 256;
printf(" extra_crap is %x \n", extra_crap);
printf(" extra_crap1 is %x \n", extra_crap1);
Unfortunately this is having no effect at all. Is there another way to remove all but the last 3 digits?
'Unfortunately this is having no effect at all.'
That's probably because you do your calculations on signed int. Try casting the value to unsigned, or simply forget the remainder operator % and use bitwise masking:
displacement & 0xFF;
displacement & 255;
for two hex digits or
displacement & 0xFFF;
displacement & 4095;
for three digits.
EDIT – some explanation
A detailed answer would be quite long... You need to learn about data types used in C (esp. int and unsigned int, which are two of most used Integral types), the range of values that can be represented in those types and their internal representation in Two's complement code. Also about Integer overflow and Hexadecimal system.
Then you will easily get what happened to your data: subtracting 0x01AE1 - 0x01AEA, that is 6881 - 6890, gave the result of -9, which in 32-bit signed integer encoded with 2's complement and printed in hexadecimal is FFFFFFF7. That MINUS NINE divided by 256 gave a quotient ZERO and Remainder MINUS NINE, so the remainder operator % gave you a precise and correct result. What you call 'no effect at all' is just a result of your lack of understanding what you were actually doing.
My answer above (variant 1) is not any kind of magic, but just a way to enforce calculation on positive numbers. Casting values to unsigned type makes the program to interpret 0xFFFFFFF7 as 4294967287, which divided by 265 (0x100 in hex) results in quotient 16777215 (0xFFFFFF) and remainder 247 (0xF7). Variant 2 does no division at all and just 'masks' those necessary bits: numbers 255 and 4095 contain 8 and 12 low-order bits equal 1 (in hexadecimal 0xFF and 0xFFF, respectively), so bitwise AND does exactly what you want: removes the higher part of the value, leaving just the required two or three low-order hex dgits.

I've created a code to convert binary to decimal, but doesn't work with more than 10 bits

I've created a small code to convert binary number to decimal number.
When I enter a binary number until 10 bits, the result be correct, but when I increase than 10 bits, the result would be wrong.
The algorithm that I used is the following
1 1 0 0 1 0
32 16 8 4 2 1 x
------------------
32+ 16+ 0+ 0+ 2+ 0
The Code:
unsigned long binary, i=0, j=0, result=0, base=1;
unsigned char *binaryStandalone = (unsigned char *)malloc(16);
memset(binaryStandalone, 0, 16);
printf("Enter a binary number: ");
scanf("%u", &binary);
while(binary > 0){
binaryStandalone[i] = binary % 10;
binary = binary / 10;
i++;
}
for(j=0;j<i;j++){
result += (binaryStandalone[j] * 1 << j);
printf("%u = %u\n", j, base << j);
}
printf("The decimal number is: %u\n", result);
free(binaryStandalone);
Now I want to know, what is the reason that the code doesn't give me the correct result when increase the binary number more than 10 bits ?
It seems that your platform uses 32 bit for a long int, therefore your binary
variable can hold at most the value 2^32 - 1 = 4294967295, which is sufficient
for 10 digits, but not for eleven.
You could use unsigned long long instead (64 bit would be sufficient for 20 digits), or read the input as a string.
you store in an unsigned long which has range 0 to 4,294,967,295 -> only 10 numbers
Because the long value you're using to store the "binary" value has not more decimal digits. You might want to use a string type for input instead.

Resources