k&r : solutions to bitwise excersises
parent
9b47cb84d0
commit
e001baa96f
|
@ -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)));
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
|
@ -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));
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue