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

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.

Related

Bitwise operations in C yields unwanted 1's or F's [duplicate]

This question already has answers here:
Right shifting negative numbers in C
(6 answers)
Closed 9 months ago.
I have a problem with C's bitwise operations and can't "merge" two numbers together.
Suppose I have the number 0x0A (or any 2 hexadecimal digits) and I want to replace the left digit with 0xF for example, That is:
00001010 -> 11111010 in terms of bitwise.
What I tried to do is the following:
We drop the left digit of the 2-digit hex number by left shifting (sizeof(int)*8-4) times, thus leaving the rightmost bits that we care about, and then right shifting (unsigned) so that we get only the right hex digit in the end. In the example above it won't matter as it'll yield 'A' which is the same as 0x0A.
The second step is to "merge" the digit we got in step one and the shifted hex digit we want to use, and we'll do that by using an OR gate.
Thus:
Hex number before and after step one: A (1010)
Desired hex digit after shifting: F0 (1111 0000)
OR gate:
00001010
OR 11110000
= 11111010 = 0xFA
However, for some reason, my C code does all of the above correctly, and just when applying OR it gives the result 0xFFFFFFFA (8-byte).
Is there something that I'm missing on how C works with bitwise?
Note that I use sizeof(int) because the code should be able to account for 4 or 8 byte int.
Thanks for help in advance!
int setHexDigit(char* digitPairPtr, int digitPos, char hexDigit)
{
int return_value = 0;
if( (hexDigit>='0' && hexDigit<='9') || (hexDigit>='A' && hexDigit <='F'))
{
if(digitPos==0)
{
hexDigit = ((hexDigit<='9' && hexDigit>='0') ? (hexDigit-'0') : ( (hexDigit>='A' && hexDigit<='F') ? (hexDigit-('A'-10)) : (-1))); //THIS LINE IS NOT IMPORTANT
*digitPairPtr = ((unsigned)*digitPairPtr<<((sizeof(int))*8-4))>>((sizeof(int))*8-4); //Drop left digit.
hexDigit = (hexDigit << 4);
*digitPairPtr = *digitPairPtr | hexDigit;
return_value=1;
}
else
{
//For later
}
}
return return_value;
}
int main()
{
char c = 0x0A;
setHexDigit(&c,0,'F');
printf("\n%X", c);
return 0;
}
I think the problem is in the printf statement. If you are using a compiler where char is signed, passing c to printf will sign extend it from 0xFA to 0xFFFFFFFA. Try using unsigned char instead.

How do I generate a random 32 bit binary number and manipulate it/ extract certain bits from it using C?

I understand that in C, to generate a random number, we use rand();
My plan is (i) to generate a 32 bit random number in binary,
(ii) Extract some specific bits from it for specific purposes.
I have tried using int rando = rand() but this at least shows a decimal representation. Which is fine by me but I need to extract certain bits from it. I tried something like:
unsigned long init32;
init32 = ((double)rand()/RAND_MAX)*0b11111111111111111111111111111111111111; printf(" The number is %lu", init32);
which did not give me a binary representation when printed out.
Like I said, I need to extract some specific bits. For example,
How should I go about generating 32 bit binary number for this purpose and then store the 10 bits for Page Table?
I hope I was clear enough. This is for a research project.
"Binary" and "decimal" are just ways to write a number. So twenty is written 20 in decimal and 10100 in binary (and 14 in hexadecimal), but it's still the number twenty in all cases.
Your printf line is:
printf(" The number is %lu", init32);
When you wrote %lu, because it ends in u you actually asked to print the value as a (positive) decimal number. While with printf you can't print values in binary directly, you can instead print it as hexadecimal, which is perfectly equivalent:
printf(" The number is %lx", init32); // For example: " The number is 14", which means the number is "10100" in binary
From the hexadecimal it's easy to find the binary of the same number because each hex character directly corresponds to a binary representation (e.g. "A" is "1010" in binary): https://www.bbc.co.uk/bitesize/guides/zp73wmn/revision/1 .
If by "extract specific bits", you mean getting the number corresponding to the bits in your schematic, you could do so with something like this (I didn't test it but this should be good or pretty close):
init32 = /* some value */;
// Basically the part on the left side of the "&" takes the entire init32
// and moves it right by that number of bits. Then to cancel the bits on the
// left that you don't want (such as to put to 0 the bits of the "directory"
// when you want to get the page table), we use bitwise "&" with the part on
// the right.
unsigned long directory = (init32 >> 22) & ((1 << (31 - 22 + 1)) - 1);
unsigned long pagetable = (init32 >> 12) & ((1 << (21 - 12 + 1)) - 1);
unsigned long offset = (init32 >> 0 ) & ((1 << (11 - 0 + 1)) - 1);
If that is confusing to you, check out "C bitwise operators" on Google. You do need to understand how numbers work in binary to see what this does though.

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.

Decimal to Binary conversion

I need to convert a 20digits decimal to binary using C programming. What buffer will I create, because it will be very large, even the calculator can't compute converting 20 digits to Binary.
here is sample of what i intend to accomplish:
Let is assume this code:
I am type this value via my keyboard into the buffer. Meanwhile, I am using an AT85C55WD Mcu.
unsigned char idata token[20]=(2,3,5,6,3,3,4,4,3,2,4,4,6,7,4,3,4,5,3,3);
I want a result
type-define variable convrt_token= 23562244324467434533;
Is this possible using C? If it is, then please how do i go about it?
each digit in decimal has 10 values, 0..9. so you'll need between 3 and 4 digits in binary. so let's say 4 to keep it simple.
so for a 20 digit decimal you'll need an 80 digit number in binary.
you can do it all with chars to keep it simple as well. i assume this is for fun.
char decnum[20];
char binnum[80];
good luck.
Here is elegent solution....:)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<unistd.h>
#include<assert.h>
#include<stdbool.h>
#define max 10000
#define RLC(num,pos) ((num << pos)|(num >> (32 - pos)))
#define RRC(num,pos) ((num >> pos)|(num << (32 - pos)))
void tobinstr(int value, int bitsCount, char* output)
{
int i;
output[bitsCount] = '\0';
for (i = bitsCount - 1; i >= 0; --i, value >>= 1)
{
output[i] = (value & 1) + '0';
}
}
int main()
{
char s[50];
tobinstr(65536,32, s);
printf("%s\n", s);
return 0;
}
Start off as Gidon mentions. Then you only need to define a function 'decToBin' or something like that, which you can use like this:
char decnum[20];
char binnum[80];
// ... get the values, do zero initialization etc...
decToBin( decnum, binnum );
And you're ready to go.
The decToBin function could easily be implemented as a common long division algorithm. That shouldn't be too hard.
Have fun ;)
EDIT: Detailed description:
Look at your last digit. Is it divisible by 2?
--> yes: your binary digit will be 0
--> no: your binary digit will be 1
Divide the entire decimal number by 2 (Long division preferrably) and truncate if necessary.
start over. You will get the binary digits in reverse order. (Repeat until your decimal number is 0)

Resources