k&r : solutions to bitwise excersises

master
Tibor Bizjak 2023-06-22 13:56:04 +02:00
parent 9b47cb84d0
commit e001baa96f
6 changed files with 194 additions and 28 deletions

View File

@ -1,11 +1,35 @@
#include "bitwise.h"
#include <stdio.h>
#include <stdlib.h>
#include "02-bitwise.h"
#define F(n) getbits(n, 4, 3)
unsigned setbits(unsigned x, int p, int n, unsigned y);
int getbits(unsigned x, int p, int n)
/* parse command line args for setbits, print result */
int main(int argc, char *argv[])
{
printf("%d\n", x);
return (x >> (p+1-n)) & ~(~0 << n);
if (argc < 5) {
printf("error : expected 4 arguments x p n y\n");
return 1;
}
unsigned x, y;
int bx = int_of_string(&x, argv[1]);
int p = atoi(argv[2]);
int n = atoi(argv[3]);
int by = int_of_string(&y, argv[4]);
if (!bx || !by) {
return 2;
}
printd_base(bx, setbits(x, p, n, y));
putchar('\n');
return 0;
}
MAIN
/* setbits: replace n bits in position p (right adjusted) in
* x with the rightmost n bits of y, return the result */
unsigned setbits(unsigned x, int p, int n, unsigned y)
{
unsigned mask = ~(~0 << n);
return ((y & mask) << (p+1-n)) | (x & ~(mask << (p+1-n)));
}

View File

@ -0,0 +1,32 @@
#include <stdio.h>
#include <stdlib.h>
#include "02-bitwise.h"
unsigned invert(unsigned x, int p, int n);
/* parse command line args for invert, print result */
int main(int argc, char *argv[])
{
if (argc < 4) {
printf("error : expected 3 arguments x p n\n");
return 1;
}
unsigned x;
int bx = int_of_string(&x, argv[1]);
int p = atoi(argv[2]);
int n = atoi(argv[3]);
if (!bx) {
return 2;
}
printd_base(bx, invert(x, p, n));
putchar('\n');
return 0;
}
/* invert: invert n bits of x at positon p (right adjusted) */
unsigned invert(unsigned x, int p, int n)
{
return x ^ (~(~0 << n) << (p-n+1));
}

View File

@ -0,0 +1,36 @@
#include <stdio.h>
#include <stdlib.h>
#include "02-bitwise.h"
unsigned rightrot(unsigned x, int n);
/* parse command line args for rightrot, print result */
int main(int argc, char *argv[])
{
if (argc < 3) {
printf("error : expected 2 arguments x n\n");
return 1;
}
unsigned x;
int bx = int_of_string(&x, argv[1]);
int n = atoi(argv[2]);
if (!bx) {
return 2;
}
printd_base(bx, rightrot(x, n));
putchar('\n');
return 0;
}
/* rightrot: right rotate x by n bit positions */
unsigned rightrot(unsigned x, int n)
{
int p = 0;
while (x >> p) {
p++;
}
n %= p;
return (x >> n) | ((~(~0 << n) & x) << (p - n));
}

View File

@ -0,0 +1,89 @@
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "02-bitwise.h"
#define BASES X("0b", 2) X("0", 8) X("", 10) X("0x", 16)
#define X(p, b) int int_of_base_##b(unsigned *x, char *s);
BASES
#undef X
/* printd_base: prints x in base b */
void printd_base(int b, unsigned x)
{
if (!x) {
putchar('0');
return;
}
switch (b) {
#define X(p, b) case b : printf("%s", p); break;
BASES
#undef X
}
unsigned m;
for (m = 1; m * b <= x && m * b > 0; m *= b)
;
char d;
while (m > 0) {
if ((d = x / m) > 9)
putchar(d - 10 + 'a');
else
putchar(d + '0');
x %= m;
m /= b;
}
}
/* int_of_string: converts string s to int, writes result to *x and returns base
* of the ints string representation or 0 if s is invalid */
int int_of_string(unsigned *x, char *s)
{
switch (*s) {
case '0' :
switch (*(s+1)) {
case 'b' :
return int_of_base_2(x, s+2);
case 'x' :
return int_of_base_16(x, s+2);
default :
return int_of_base_8(x, s+1);
}
default :
return int_of_base_10(x, s);
}
return 0;
}
/* int_of_base_b: for base b, convert number string in base b to int and
* write it to *x. return b or 0 if invalid */
#define MAKE_INT_OF_BASE(b) \
int int_of_base_##b(unsigned *x, char *s) \
{ \
char d; \
unsigned px = 0; \
*x = 0; \
for (; *s; s++) { \
d = *s - '0'; \
if (b > 10 && d > 9) \
d = tolower(*s) - 'a' + 10; \
if (d < 0 || d >= b) { \
printf("error: invalid character in number literal in base " #b "\n"); \
return 0; \
} \
px = *x; \
*x *= b; \
*x += d; \
if (*x < px) { \
printf("error : number to large\n"); \
return 0; \
} \
} \
return b; \
}
#define X(p, b) MAKE_INT_OF_BASE(b)
BASES
#undef X

View File

@ -0,0 +1,7 @@
#ifndef BITWISE_H
#define BITWISE_H
int int_of_string(unsigned *x, char *s);
void printd_base(int base, unsigned x);
#endif // BITWISE_H

View File

@ -1,22 +0,0 @@
#ifndef BITWISE_H
#define BITWISE_H
#include <stdio.h>
unsigned int int_of_bin(char bs[]);
void print_bin(unsigned int n);
/* standard main, applies function F to binary
* input and prints result (in binary) */
#define MAIN \
int main(int argc, char *argv[]) \
{ \
if (argc < 0) { \
printf("error : expected binary string argument\n"); \
return 1; \
} \
print_bin(F(int_of_bin(argv[1]))); \
putchar('\n'); \
} \
#endif // BITWISE_H