i have a problem, i have to learn for the next week exam and i have the following exercise
Set the bit position to n and clears the bit to the left of that position. For a=0x20 and n=5 it should be 0x10 and for a=0xFB and n=2 it should be 0xF7.
I tried the n+1 considering the 6th bit is in the left of the 5th, but it doesn`t work, thank you in advance.
int main() {
unsigned char a = 0x20;
unsigned char b;
unsigned char c;
int n = 5;
// setting the bit to n position
b = a | (1 << n);
//clearing the left bit of n position
c = b & ~(1<<(n+1));
printf("The result is: 0x%x\n", c);
return 0;
}
The example is inconsistent, but assuming n is a bit index (goes from 0 to length-1):
unsigned solve(unsigned a, unsigned n)
{
unsigned result = 0;
unsigned pmask = 1U<<n;
unsigned nmask = ~(pmask<<1);
result = a|pmask;
result = result&nmask;
return result;
}
Related
I have an issue i can't solve. The code below should get a number from the user and a number of rotations. The code should calculate the number after the rotations. For negative number of rotations the code should rotate the number left and for positive number of rotation the code should rotate the number right.
For example: for the input x=1010111011111011
my_rotate(x, -3) will return 0111010111011111
my_rotate(x, 3) will return 0111011111011101
Here is the code i wrote so far:
#include <stdio.h>
unsigned short my_rotate(unsigned short, char);
int main()
{
unsigned short num, res;
char rotations;
printf("\nPlease enter a number and number of rotations\n");
scanf("%hu %d", &num, &rotations);
res = my_rotate(num, rotations);
return 0;
}
unsigned short my_rotate(unsigned short a, char b)
{
unsigned short bitsNum = sizeof(unsigned short) * 8;
unsigned short temp1, temp2, result;
if(b == 0)
return a;
else if(b < 0)
{
temp1 = a << (bitsNum + b);
temp2 = a >> (-b);
result = temp1 + temp2;
}
else /* b > 0 */
{
temp1 = (a >> (bitsNum - (unsigned short)b));
temp2 = (a << (unsigned short)b);
result = temp1 + temp2;
}
return result;
}
I always get 0 as a result and i don't know why. What's wrong with my code?
in main :
unsigned short num, res;
char rotations;
printf("\nPlease enter a number and number of rotations\n");
scanf("%hu %d", &num, &rotations);
the last argument of scanf must be a pointer to an int (format is %d) but you give the address of a char, the behavior is undefined. Use an int for rotations for the format %d
In my_rotate b is a char and you do if(b < 0), the result depends if the char are signed or not, type n with signed char if you expect a char to be signed
If rotations is an int and b a signed char :
44795 (1010111011111011) and -3 produce 30175 being 111010111011111
44795 (1010111011111011) and 3 produce 30685 being 111011111011101
as you expected.
Note for me an unsigned short is on 16 bits, of course the result is not the same if short are on a different number of bit.
#bruno well explained a problem with input.
A rotation count may exceed +/- bitsNum, so a good first step is to limit the rotation count.
unsigned short my_rotate(unsigned short a, int b) {
unsigned short bitsNum = sizeof(unsigned short) * 8;
//add
b %= bitsNum;
....
Highly portable code would not use bitsNum as that is derived by the size of unsigned short (and assumes 8 bits/char) and an unsigned short could have padding bits. Certainly this is more of a rare machine concern. Code should derive the bit width based on USHRT_MAX instead.
poly8_bitslice() array if char as input, this input will be converted to bits(byte) by the function intToBits().
After the conversion I want to store the result in a long long variable. Is this possible?
Can I concatenate the result of intToBits()?
I want to do this with the following code:
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <string.h>
//#include <math.h>
typedef unsigned char poly8;
typedef unsigned long long poly8x64[8];
void intToBits(unsigned k, poly8 nk[8]) {
int i;
for(i=7;i>=0;i--){
nk[i] = (k%2);
k = (int)(k/2);
}
}
void poly8_bitslice(poly8x64 r, const poly8 x[64])
{
//TODO
int i;
for(i=0;i<64;i++){
poly8 xb[8];
intToBits(x[i], xb);
int j;
long long row;
for(j=0;j<8;j++){
row = row + x[j];
}
printf("row=%d \n", row);
}
}
int main()
{
poly8 a[64], b[64], r[64];
poly8x64 va, vb, vt;
int i;
FILE *urandom = fopen("/dev/urandom","r");
for(i=0;i<64;i++)
{
a[i] = fgetc(urandom);
b[i] = fgetc(urandom);
}
poly8_bitslice(va, a);
poly8_bitslice(vb, b);
fclose(urandom);
return 0;
}
I am not sure I fully understood your question but you can do something like this
char ch0 = 0xAA;
char ch1 = 0xBB;
char ch2 = 0xCC;
char ch3 = 0xDD;
long long int x = 0; // x is 0x00000000
x = (long long int)ch0; // x is 0x000000AA
x = x << 8; // x is 0x0000AA00
x = x | (long long int)ch1; // x is 0x0000AABB
x = x << 8; // x is 0x00AABB00
x = x | (long long int)ch2; // x is 0x00AABBCC
x = x << 8; // x is 0xAABBCC00
x = x | (long long int)ch3; // x is 0xAABBCCDD
In this case x would contain 0xAABBCCDD
The << operator will shift the content of the left hand operator by the number specified by the right hand operator. So 0xAA << 8 would become 0xAA00. Note that it will append zeros at the end while shifting.
The| operator will perform a bitwise or on both its operands. That is a bit by bit or. So the first bit of the left hand operator will be or'ed with the first bit of the right hand operator and the result will be placed in the first bit of the result.
Anything or'ed with zero results to its self so
0xAA00 | 0x00BB
would result in
0xAABB
In general a bit append function would be
long long int bitAppend(long long int x, char ch) {
return ((x << 8) | (long long int)ch);
}
This function would take the long long integer that you need to append to and the char to append to it and would return the appended long long int. Note that as soon as the 64 bits are filled up the high order bits will be shifted out.
For example
long long int x = 0x1122334455667788
x = x << 8; // x now is 0x2233445566778800
this would result into x being 0x2233445566778800 since there is only 64bits in a long long int so the high order bits had to move out.
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.
So I am trying to implement this algorithm in C for multiplying 32-bit unsigned int in order to understand it better:
Step 1: Test multiplier-0
Step 2: if 1, add multiplicand to left half of product
and place the result in the left half of
the product register
Step 3: shift multiplier right 1 bit
Step 4: shift product register right 1 bit
What I am not getting is how to implement step 2. It says to add multiplicand to left half of product and store in left half of product register. I am confused on how to add only to the left half of the product. How do I go about this?
EDIT:
This is something I came with but it does not give me the right answer and I am not sure what is going wrong. Please help!
long unsigned UnsignedMult(unsigned multiplicand, unsigned multiplier){
unsigned int temp32a, temp32b;
unsigned long temp64;
unsigned long product;
int i;
product = multiplier;
temp32b = multiplicand;
for(i=0; i < 32; i++){
if((product & 1)==1){ //add
temp64 = product;
temp64 = temp64 >> 32;
temp32a = temp64;
product = BinaryAdd(temp32a, temp32b);
}
product = product >>= 1;
}
return product;
}
int BinaryAdd(int in1, int in2){
int sum, carry;
sum = in1 ^ in2; // x XOR y
carry = in1 & in2; // x AND y carry in
int i;
for (i = 0; i < 32; i++) {
carry = carry << 1;
in1 = sum;
in2 = carry;
sum = in1 ^ in2; //calculate sum
carry = in1 & in2; //find carry out
}
return sum;
}
Your product register needs to be 64 bits in length to allow two 32 bit integers to be multiplied. Hopefully you have uint64_t available in your compiler to represent this (stdint.h).
To do the addition, you could put your multiplicand into a 64 bit integer, shift it left 32 bits, and then add it to the 64 bit product register.
Something like:
uint64_t tmpMulti;
uint64_t productRegister = 0;
uint32_t multiplicand = 123;
tmpMulti = multiplicand;
tmpMulti <<= 32;
productRegister += tmpMulti;
(Apologies for any syntax mistakes, I haven't written C code in a long time)
Out of interest, I had a go at implementing it myself. This seems to work:
#include <stdio.h>
#include <stdint.h>
void main(int argc, char* argv[])
{
uint32_t multiplier = 17;
uint32_t multiplicand = 12;
uint64_t productRegister = multiplier;
for (int n = 0; n < 32; n++) {
if (productRegister & 1 == 1) {
productRegister += ((uint64_t)multiplicand) << 32;
}
productRegister >>= 1;
}
printf("Result: %d\n", productRegister);
}
The following code does not use <stdint.h>, and uses two 32 bit ints to represent the 64 bit product register. It doesn't attempt to handle overflow, and assumes the answer will fit in 32 bits.
#include <stdio.h>
void main(int argc, char* argv[])
{
unsigned int multiplier = 17;
unsigned int multiplicand = 12;
unsigned int productRegisterLower = multiplier;
unsigned int productRegisterUpper = 0;
for (int n = 0; n < 32; n++) {
if (productRegisterLower & 1 == 1) {
productRegisterUpper += multiplicand;
}
productRegisterLower >>= 1;
productRegisterLower |= productRegisterUpper << 31;
productRegisterUpper >>= 1;
}
printf("Result: %d\n", productRegisterLower);
}
In order to handle the right shift of the product register, it moves the least significant bit of the upper half into the most significant bit of the lower half. To do this, it:
Shifts the lower half to the right 1 bit.
Takes a copy of the upper half and shifts it left 31 bits, so that the least significant bit is now on the left, and the rest of the value is zero.
ORs this with the lower half, to copy the shifted bit across.
Shifts the upper half to the right 1 bit.
I have a program that my professor gave me for a HW, and I want to see if any of y'all can explain me how bits work. Note: I don't want you guys to give me the answer; I want to learn so if you guys can explain me how this work would be awesome so I can go ahead an start on my hw.
Instructions:
a) unsigned setbits (unsigned x, int p, int n, unsigned y) that returns x with the n bits that begin at position p (right-adjusted) set to the rightmost n bits of y, leaving the other bits unchanged. Note: it does not change the values of x and y though.
b) unsigned invertbits (unsigned x, int p, int n) that returns x with the n bits that begin at position p (right-adjusted) inverted, i.e. 1 changed to 0 and vice versa, leaving the other bits unchanged. Note: it does not change the value of x though.
#include <stdio.h>
#include <limits.h>
void bit_print(int);
int pack(char, char, char, char);
char unpack(int, int);
unsigned getbits(unsigned, int, int);
void bit_print(int a){
int i;
int n = sizeof(int) * CHAR_BIT;
int mask = 1 << (n-1); // mask = 100...0
for (i=1; i<=n; i++){
putchar(((a & mask) == 0)? '0' : '1');
a <<= 1;
if (i % CHAR_BIT == 0 && i < n)
putchar(' ');
}
putchar('\n');
}
int pack(char a, char b, char c, char d){
int p=a;
p = (p << CHAR_BIT) | b;
p = (p << CHAR_BIT) | c;
p = (p << CHAR_BIT) | d;
return p;
}
char unpack(int p, int k){ // k=0, 1, 2, or 3
int n = k * CHAR_BIT; // n = 0, 8, 16, 24
unsigned mask = 255; // mask = low-order byte
mask <<= n;
return ((p & mask) >> n);
}
// getbits() extracts n bits from position p(start counting from the right-most bit) in x
unsigned getbits(unsigned x, int p, int n){
unsigned temp = x >> (p+1-n);
unsigned mask = 0;
mask = ~mask;
mask = mask << n;
mask = ~mask;
return temp & mask;
// return (x >> (p+1-n)) & ~(~0<<n);
}
int main(){
int x = 19;
printf("The binary rep. of %d is:\n", x);
bit_print(x);
int p=pack('w', 'x', 'y', 'z');
printf("\n'w', 'x', 'y', and 'z' packed together is equal to %d. Its binary rep. is:\n", p);
bit_print(p);
printf("calling unpack(p, 0) to extract the byte # 0 from the right:\n");
bit_print(unpack(p, 0));
printf("calling unpack(p, 1) to extract the byte # 1 from the right:\n");
bit_print(unpack(p, 1));
printf("calling unpack(p, 2) to extract the byte # 2 from the right:\n");
bit_print(unpack(p, 2));
printf("calling unpack(p, 3) to extract the byte # 3 from the right:\n");
bit_print(unpack(p, 3));
unsigned result = getbits(p, 20, 7);
printf("\ncalling getbits(p, 20, 7) to extract 7 bits from bit # 20 returns %d:\n", result);
bit_print(result);
return 0;
}
Using bitwise AND & , OR |, XOR ^, NOT ~ and a proper bit mask you can manipulate bits inside a variable. You will also need bit shifts >> and <<.
So let us have an example:
Let's take a 8bit var x = 0xff and try to invert its 3'rd bit:
unsigned char x = 0xff; // Our var
unsigned char mask = 1<<3; // Our mask
x = x & ~mask; // Invert mask so its value is b1111_0111
// and make a bitwise AND with x
Every bit in x keeps its value if there is 1 in a mask, and turns into 0 when masks bit value is 0. Now x value is x = 0xf7.
Using other operators you can do whatever you want with bits :)
So for example yours unpack function does:
char unpack(int p, int k){ // k - byte offset
int n = k * CHAR_BIT; // n - bit offset (k * 8)
unsigned mask = 255; // mask with all ones at first byte (0x000f)
mask <<= n; // move mask left n times;
// Now the ones are at the k'th byte
// if k = 2 => mask = 0x0f00
return ((p & mask) >> n); // Mask out k'th byte of p and remove all zeros
// from beginning.
}
When p = 0x3579 and k = 1:
n = k * CHAR_BIT; // n = 8
mask = 255; // mask = 0x000f
mask <<= n; // mask = 0x00f0
p &= mask; // p = 0x0070
p >>= n; // p = 0x0007
I hope it will help you!