I am using ubuntu x86_64 machine and trying to set the bit position corresponding to the character in string.
Character can a-z or A-Z, so I have kept a 64 bit vector.
long unsigned int vector = 0x0;
char *getunqchar(char a[]) {
char str[30];
int i;
long unsigned int t, test = 0;
for (i = 0; i < strlen(a) - 1; i++) {
t = (long unsigned int)(a[i]) - 65;
printf("t is %ld", t);
test = (long unsigned int)(1 << t);
vector = (vector ) | test;
printf("vec is %ld %ld \n", (long unsigned int)vector, (long unsigned int)test);
}
}
int main() {
int i = 0;
char name[30], *temp;
int cnt[52], t;
memset(cnt, 0, sizeof(cnt));
printf("vec is %lx", vector);
printf("Enter the string name: ");
fgets(name, sizeof(name), stdin);
temp = getunqchar(name);
}
when I input like below:
Enter the string name: mAn
t is 44vec is 4096 4096
t is 0vec is 4097 1
t is 45vec is 12289 8192
t value is 44, I expect output as 2^44 but I am getting 2^12.
44 is 32 + 12. It seems to be some issue because of 64 bit. But I am not getting. Any help is appreciated.
1 << t is evaluated as int, use 1UL << t to evaluate as unsigned long.
Related
Hi all I am writing a C program that asks the user for an unsigned integer. The program will then call a function
unsigned int reverse_bits(unsigned int n)
This function should return an unsigned integer whose bits are the same as those of n but in reverse
order.
Print to screen the integer whose bits are in reverse order.
Example:
User enters:
12 (binary 16 bits is 0000000000001100)
Program print to screen:
12288 (0011000000000000)
This is the code i have but it does not output the right answer:
#include <stdio.h>
//function prototype
unsigned int reverse_bits(unsigned int n);
int main(void) {
unsigned int n;
unsigned int bits;
printf("Enter an unsigned integer: ");
scanf("%u",&n);
bits = reverse_bits(n);
printf("%u\n",bits);
return 0;
}
unsigned int reverse_bits(unsigned int n) {
unsigned int reverse = 0;
while (n > 0) {
reverse = reverse << 1;
if((n & 1) == 1) {
reverse = reverse | 1;
}
n = n >> 1;
}
return reverse;
}
This does not give me 12288 when I enter 12, it gives me 3, what did I do wrong?
The result depends on how many bits an unsigned int is stored on your machine. It is usually 4 bytes (32 bits). So, in your case 12 (00000000000000000000000000001100 in binary) becames 805306368 (00110000000000000000000000000000 in binary).
Apart from that, you need to iterate over all bits of an unsigned int:
for (size_t i = 0; i < sizeof(unsigned int) * 8; i++) {
reverse = reverse << 1;
if((n & 1) == 1) {
reverse = reverse | 1;
}
n = n >> 1;
}
I was given a task at the university, there is a number and I need to display it in HEX as it is presented on the computer. I wrote a program for translating signed integers. And I also found a real number entry in HEX. But it is different from the usual.
For integers i use: printf("%#X", d);
For reals i use: printf("%#lX", r);
If i input 12, first prints: 0xC
If i input 12.0, second prints: 0x4028000000000000
Can you explain what the difference and how it's calculate?
Printing double value r using format %#lX actually has undefined behavior.
You have been lucky to get the 64-bits that represent the value 12.0 as a double, unless r has type unsigned long and was initialized from the value 12.0 this way:
unsigned long r;
double d = 12.0;
memcpy(&r, &d, sizeof r);
printf("%#lX", r);
But type unsigned long does not have 64-bits on all platforms, indeed it does not on the 32-bit intel ABI. You should use the type uint64_t from <stdint.h> and the conversion format from <inttypes.h>:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
int main() {
int x = 12;
printf("int: %#X [", x);
for (size_t i = 0; i < sizeof x; i++) {
printf(" %02X", ((unsigned char *)&x)[i]);
}
printf(" ]\n");
double d = 12.0;
uint64_t r;
memcpy(&r, &d, sizeof r);
printf("double: %#"PRIX64" [", r);
for (size_t i = 0; i < sizeof d; i++) {
printf(" %02X", ((unsigned char *)&d)[i]);
}
printf(" ]\n");
printf("sign bit: %d\n", (int)(r >> 63));
printf("exponent: %d\n", (int)((r >> 52) & 2047));
unsigned long long mantissa = r & ((1ULL << 52) - 1);
printf("mantissa: %#llX, %.17f\n",
mantissa, 1 + (double)mantissa / (1ULL << 52));
return 0;
}
Output:
int: 0XC [ 0C 00 00 00 ]
double: 0X4028000000000000 [ 00 00 00 00 00 00 28 40 ]
sign bit: 0
exponent: 1026
mantissa: 0X8000000000000, 1.50000000000000000
As explained in the article Double-precision floating-point format, this representation corresponds to a positive number with value 1.5*21026-1023, ie: 1.5*8 = 12.0.
The X format specifier expects an int or unsigned int argument. With the l modifier it expects a long or unsigned long int argument. If you call it with anything else (such as a double) you get undefined behavior.
If you want to print a hex float (with uppercase letters), use %A format, which for 12.0 will print 0X1.8P+3 -- 1½×23
To produce the encoding of a number in hex is a simple memory dump.
The process is not so different among types.
The below passes the address of the object and its size to form a string for printing.
#include <stdio.h>
#include <assert.h>
#include <limits.h>
// .... compound literal ....................
#define VAR_TO_STR_HEX(x) obj_to_hex((char [(sizeof(x)*CHAR_BIT + 3)/4 + 1]){""}, &(x), sizeof (x))
char *obj_to_hex(char *dest, void *object, size_t osize) {
const unsigned char *p = (const unsigned char *) object;
p += osize;
char *s = dest;
while (osize-- > 0) {
p--;
unsigned i = (CHAR_BIT + 3)/4;
while (i-- > 0) {
unsigned digit = (*p >> (i*4)) & 15;
*s++ = "0123456789ABCDEF"[digit];
}
}
*s = '\0';
return dest;
}
int main(void) {
double d = 12.0;
int i = 12;
printf("double %s\tint %s\n", VAR_TO_STR_HEX(d), VAR_TO_STR_HEX(i) );
d = -d;
i = -i;
printf("double %s\tint %s\n", VAR_TO_STR_HEX(d), VAR_TO_STR_HEX(i) );
return 0;
}
Output
double 4028000000000000 int 0000000C
double C028000000000000 int FFFFFFF4
With more complex objects, the output may include padding bits/bytes and the output is sensitive to endian.
I have a string say:
char *hexstring = "08fc0021";
this is a concatenation of two information each two bytes long.
The first two bytes of this string, ie.: 08fc corresponds to 2300 in dec.
the last 4 bytes, ie., 0021 -> 33.
My problem is to convert this string into two different variables, say:
int varA, varB;
here varA will have the number 2300, and varB = 33.
normally I would have used sscanf to convert the string into a decimal num.
but now i have this problem of a concatenated string with two different info.
any idea suggestion how to nail this ?
thx in advance
Bitwise AND to the Rescue!
So, doing what you require can be done using the bitwise AND opperator on the resulting 32bit number (int?) you get from sscanf.
You first get the number from the string:
char* hexstring = "0x08fc0021";
int num = 0;
sscanf(hexstring, "%x", &num); //put the number into num.
Then you get the bits you want using &:
int varA=0, varB=0;
varA = num & 0xFFFF; //will get the second half.
varB = num & 0xFFFF0000;
varB = varB >> 16; // now you have the first half as well.
And there you have it.
int main(int argc, char *argv[]) {
char *hexstring = "08fc0021";
unsigned long hexnumber = 0u;
unsigned short a = 0u;
unsigned short b = 0u;
/* Use sscanf() to convert the string to integer */
sscanf(hexstring, "%x", &hexnumber);
/* Use bitwise and to filter out the two higher bytes *
* and shift it 16 bits right */
a = ((hexnumber & 0xFFFF0000u) >> 16u);
/* Use bitwise AND to filter out the two lower bytes */
b = (hexnumber & 0x0000FFFFu);
printf("0x%X 0x%X\n",a,b);
return 0;
}
You can use this approach (bit operations):
char *hexstring = "08fc0021";
int aux;
sscanf(hexstring, "%x", &aux);
printf("aux = 0x%x = %d\n", aux, aux);
int varA = (aux & 0xFFFF0000) >> 16, varB = aux & 0x0000FFFF;
printf("varA = 0x%x = %d\n", varA, varA);
printf("varB = 0x%x = %d\n", varB, varB);
Result:
aux = 0x8fc0021 = 150732833
varA = 0x8fc = 2300
varB = 0x21 = 33
EDIT:
Or this approach (string manipulation):
// requires a hexstring length of 8 or more sophisticated logic
char *hexstring = "08fc0021";
int len = strlen(hexstring);
char varA[5], varB[5];
for(int i = 0; i<len; i++)
{
if(i < 4) varA[i] = hexstring[i];
else varB[i-4] = hexstring[i];
}
varA[4] = varB[4] = '\0';
int varAi, varBi;
sscanf(varA, "%x", &varAi);
sscanf(varB, "%x", &varBi);
printf("varAi = 0x%x = %d\n", varAi, varAi);
printf("varBi = 0x%x = %d\n", varBi, varBi);
Same result:
varAi = 0x8fc = 2300
varBi = 0x21 = 33
You are given a getTemps() function returns an integer composed of: the daily high temperature
in bits 20-29, the daily low temperature in bits 10-19, and the current temperature in bits 0-9, all
as 2's complement 10-bit integers.
Write a C program which extracts the high, low, and current temperature and prints the values.
I am given this situation. So my question is how do I get the specific segments of an integer.
So far I have:
#include <stdio.h>
unsigned createMask(unsigned a, unsigned b){
unsigned r = 0;
unsigned i;
for (i=a; i<=b; i++){
r |= 1 << i;
}
return r;
}
int main(int argc, char *argv[])
{
unsigned r = createMask(29,31);
int i = 23415;
unsigned result = r & i;
printf("%d\n", i);
printf("%u\n", result);
}
The integer 23415 for example would have the binary 00000000 00000000 01011011 01110111
Then bits 29 through 31 for example should be 111 or integer -1 since its 2's complement.
There are three basic approaches for extracting encoded information from a bitfield. The first two are related and differ only in the manner the bitfield struct is initialized. The first and shortest is to simply create a bitfield struct defining the bits associated with each member of the struct. The sum of the bits cannot exceed sizeof type * CHAR_BIT bits for the type used to create the bitfield. A simple example is:
#include <stdio.h>
typedef struct {
unsigned cur : 10,
low : 10,
high : 10;
} temps;
int main (void) {
unsigned n = 0; /* encoded number of temps */
n = 58; /* fill number (58, 46, 73) */
n |= (46 << 10);
n |= (73 << 20);
temps t = *(temps *)&n; /* initialize struct t */
/* output value and temps */
printf ("\n number entered : %u\n\n", n);
printf (" %2hhu - %2hhu value : %u (deg. F)\n", 0, 9, t.cur);
printf (" %2hhu - %2hhu value : %u (deg. F)\n", 10, 19, t.low);
printf (" %2hhu - %2hhu value : %u (deg. F)\n\n", 20, 29, t.high);
return 0;
}
Note: memcpy can also be used to initialize the value for the structure to avoid casting the address of n. (that was done intentionally here to avoid inclusion of string.h).
The next method involves creation of a union between the data type represented and the exact same struct discussed above. The benefit of using the union is that you avoid having to typecast, or memcpy a value to initialize the struct. You simply assign the encoded value to the numeric type within the union. The same example using this method is:
#include <stdio.h>
typedef struct {
unsigned cur : 10,
low : 10,
high : 10;
} temps;
typedef union {
temps t;
unsigned n;
} utemps;
int main (void) {
unsigned n = 0; /* encoded number of temps */
n = 58; /* fill number (58, 46, 73) */
n |= (46 << 10);
n |= (73 << 20);
utemps u; /* declare/initialize union */
u.n = n;
/* output value and temps */
printf ("\n number entered : %u\n\n", n);
printf (" %2hhu - %2hhu value : %u (deg. F)\n", 0, 9, u.t.cur);
printf (" %2hhu - %2hhu value : %u (deg. F)\n", 10, 19, u.t.low);
printf (" %2hhu - %2hhu value : %u (deg. F)\n\n", 20, 29, u.t.high);
return 0;
}
Finally, the third method uses neither a struct or union and simply relies on bit shift operations to accomplish the same purpose. A quick example is:
#include <stdio.h>
#include <limits.h> /* for CHAR_BIT */
int main (void) {
unsigned n = 0; /* encoded number of temps */
unsigned char i = 0; /* loop counter */
unsigned char r = 10; /* number of bits in temps */
unsigned char s = 0; /* shift accumulator */
unsigned v = 0; /* extracted value */
n = 58; /* fill number (58, 46, 73) */
n |= (46 << 10);
n |= (73 << 20);
printf ("\n number entered : %u\n\n", n);
/* extract and output temps from n */
for (i = 0; i < (sizeof n * CHAR_BIT)/r; i++)
{
v = (n >> i * r) & 0x3ff;
printf (" %2hhu - %2hhu value : %u (deg. F)\n", s, s + r - 1, v);
s += r;
}
printf ("\n");
return 0;
}
Note: you can automate the creation of the mask with the createMask function. While longer, the shift method is not computationally intensive as shift operations take little to accomplish. While negligible, the multiplication could also be replaced with a shift and addition to further tweak performance. The only costly instruction is the division to set the loop test clause, but again it is negligible and all of these cases are likely to be optimized by the compiler.
All of the examples above produce exactly the same output:
$ ./bin/bit_extract_shift
number entered : 76593210
0 - 9 value : 58 (deg. F)
10 - 19 value : 46 (deg. F)
20 - 29 value : 73 (deg. F)
You can use union and bit field to do it. Try something like this:
struct TEM_BITS {
unsigned int tem_high :10;
unsigned int tem_low :10;
unsigned int tem_cur :10;
};
union TEM_U {
int tem_values;
struct TEM_BITS bits;
}
TEM_U t;
t.tem_values = 12345;
printf("tem_high : 0x%X\n", t.bits.tem_high);
printf("tem_low : 0x%X\n", t.bits.tem_low);
printf("tem_cur : 0x%X\n", t.bits.tem_cur);
I might have my bits backwards, but the following should be close.
int current=x&0x3ff;
int low = (x>>10)&0x3ff;
int high = (x>>20)&0x3ff;
I have tried to implement crc in c.My logic is not very good.What I have tried is to copy the message(msg) in a temp variable and at the end I have appended number of zeros 1 less than the number of bits in crc's divisor div.
for ex:
msg=11010011101100
div=1011
then temp becomes:
temp=11010011101100000
div= 10110000000000000
finding xor of temp and div and storing it in temp
gives temp=01100011101100000 counting number of zeros appearing before the first '1' of temp and shifting the characters of div right to that number and then repeating the same process until decimal value of temp becomes less than decimal value of div. Which gives the remainder.
My problem is when I append zeros at the end of temp it stores 0's along with some special characters like this:
temp=11010011101100000$#UFI#->Jp#|
and when I debugged I got error
Floating point:Stack Underflow
here is my code:
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<string.h>
void main() {
char msg[100],div[100],temp[100];
int i,j=0,k=0,l=0,msglen,divlen,newdivlen,ct=0,divdec=0,tempdec=0;
printf("Enter the message\n");
gets(msg);
printf("\nEnter the divisor\n");
gets(div);
msglen=strlen(msg);
divlen=strlen(div);
newdivlen=msglen+divlen-1;
strcpy(temp,msg);
for(i=msglen;i<newdivlen;i++)
temp[i]='0';
printf("\nModified Temp:");
printf("%s",temp);
for(i=divlen;i<newdivlen;i++)
div[i]='0';
printf("\nModified div:");
printf("%s",div);
for(i=newdivlen;i>0;i--)
divdec=divdec+div[i]*pow(2,j++);
for(i=newdivlen;i>0;i--)
tempdec=tempdec+temp[i]*pow(2,k++);
while(tempdec>divdec)
{
for(i=0;i<newdivlen;i++)
{
temp[i]=(temp[i]==div[i])?'0':'1';
while(temp[i]!='1')
ct++;
}
for(i=newdivlen+ct;i>ct;i--)
div[i]=div[i-ct];
for(i=0;i<ct;i++)
div[i]='0';
tempdec=0;
for(i=newdivlen;i>0;i--)
tempdec=tempdec+temp[i]*pow(2,l++);
}
printf("%s",temp);
getch();
}
and this part of the code :
for(i=newdivlen;i>0;i--)
divdec=divdec+div[i]*pow(2,i);
gives error Floating Point:Stack Underflow
The problem is that you wrote a 0 over the NUL terminator, and didn't put another NUL terminator on the string. So printf gets confused and prints garbage. Which is to say that this code
for(i=msglen;i<newdivlen;i++)
temp[i]='0';
printf("\nModified Temp:");
printf("%s",temp);
should be
for(i=msglen;i<newdivlen;i++)
temp[i]='0';
temp[i] = '\0'; // <--- NUL terminate the string
printf("\nModified Temp:");
printf("%s",temp);
You have to do this with integers
int CRC(unsigned int n);
int CRC_fast(unsigned int n);
void printbinary(unsigned int n);
unsigned int msb(register unsigned int n);
int main()
{
char buf[5];
strcpy(buf, "ABCD");
//convert string to number,
//this is like 1234 = 1*1000 + 2*100 + 3*10 + 4, but with hexadecimal
unsigned int n = buf[3] * 0x1000000 + buf[2] * 0x10000 + buf[1] * 0x100 + buf[3];
/*
- "ABCD" becomes just a number
- Any string of text can become a sequence of numbers
- you can work directly with numbers and bits
- shift the bits left and right using '<<' and '>>' operator
- use bitwise operators & | ^
- use basic math with numbers
*/
//finding CRC, from Wikipedia example:
n = 13548; // 11010011101100 in binary (14 bits long), 13548 in decimal
//padding by 3 bits: left shift by 3 bits:
n <<= 3; //11010011101100000 (now it's 17 bits long)
//17 is "sort of" the length of integer, can be obtained from 1 + most significant bit of n
int m = msb(n) + 1;
printf("len(%d) = %d\n", n, m);
int divisor = 11; //1011 in binary (4 bits)
divisor <<= (17 - 4);
//lets see the bits:
printbinary(n);
printbinary(divisor);
unsigned int result = n ^ divisor;// XOR operator
printbinary(result);
//put this in function:
n = CRC(13548);
n = CRC_fast(13548);
return 0;
}
void printbinary(unsigned int n)
{
char buf[33];
memset(buf, 0, 33);
unsigned int mask = 1 << 31;
//result in binary: 1 followed by 31 zero
for (int i = 0; i < 32; i++)
{
buf[i] = (n & mask) ? '1' : '0';
//shift the mask by 1 bit to the right
mask >>= 1;
/*
mask will be shifted like this:
100000... first
010000... second
001000... third
*/
}
printf("%s\n", buf);
}
//find most significant bit
unsigned int msb(register unsigned int n)
{
unsigned i = 0;
while (n >>= 1)
i++;
return i;
}
int CRC(unsigned int n)
{
printf("\nCRC(%d)\n", n);
unsigned int polynomial = 11;
unsigned int plen = msb(polynomial);
unsigned int divisor;
n <<= 3;
for (;;)
{
int shift = msb(n) - plen;
if (shift < 0) break;
divisor = polynomial << shift;
printbinary(n);
printbinary(divisor);
printf("-------------------------------\n");
n ^= divisor;
printbinary(n);
printf("\n");
}
printf("result: %d\n\n", n);
return n;
}
int CRC_fast(unsigned int n)
{
printf("\nCRC_fast(%d)\n", n);
unsigned int polynomial = 11;
unsigned int plen = msb(polynomial);
unsigned int divisor;
n <<= 3;
for (;;)
{
int shift = msb(n) - plen;
if (shift < 0) break;
n ^= (polynomial << shift);
}
printf("result: %d\n\n", n);
return n;
}
Previous problems with string method:
This is infinite loop:
while (temp[i] != '1')
{
ct++;
}
Previous problems with string method:
This one is too confusing:
for (i = newdivlen + ct; i > ct; i--)
div[i] = div[i - ct];
I don't know what ct is. The for loops are all going backward, this makes the code faster sometimes (maybe 1 nanosecond faster), but it makes it very confusing.
There is another while loop,
while (tempdec > divdec)
{
//...
}
This may go on forever if you don't get the expected result. It makes it very hard to debug the code.