Skip to content

Instantly share code, notes, and snippets.

@ultraist
Created June 7, 2011 17:30
Show Gist options
  • Save ultraist/1012697 to your computer and use it in GitHub Desktop.
Save ultraist/1012697 to your computer and use it in GitHub Desktop.
ビット演算を使わずにビット演算する
/* 決まったやり方がありそうだけど、適当にやる */
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <limits.h>
#include <assert.h>
#define BIT_M 32
#define N 10000
unsigned int
bit_not(unsigned int v)
{
int i;
unsigned int ret = 0;
for (i = BIT_M; i >= 0; --i) {
unsigned int c = (unsigned int)pow(2.0, i);
if (v >= c) {
v -= c;
} else {
ret += c;
}
}
return ret;
}
unsigned int
bit_or(unsigned int v, unsigned int bits)
{
int i;
unsigned int ret = 0;
for (i = BIT_M; i >= 0; --i) {
unsigned int c = (unsigned int)pow(2.0, i);
int on = 0;
if (bits >= c) {
bits -= c;
on = 1;
}
if (v >= c) {
v -= c;
ret += c;
} else {
if (on) {
ret += c;
}
}
}
return ret;
}
unsigned int
bit_and(unsigned int v, unsigned int bits)
{
int i;
unsigned int ret = 0;
for (i = BIT_M; i >= 0; --i) {
unsigned int c = (unsigned int)pow(2.0, i);
int on = 0;
if (bits >= c) {
bits -= c;
on = 1;
}
if (v >= c) {
v -= c;
if (on) {
ret += c;
}
}
}
return ret;
}
unsigned int
bit_shift_right(unsigned int v, int n)
{
unsigned int c = (unsigned int)pow(2.0, n);
return v / c;
}
unsigned int
bit_shift_left(unsigned int v, int n)
{
unsigned int c = (unsigned int)pow(2.0, n);
return v * c;
}
int
main(void)
{
unsigned int i;
for (i = 0; i < N; ++i) {
unsigned int bit = (unsigned int)(((double)rand() / RAND_MAX) * 32);
unsigned int mask = (unsigned int)(((double)rand() / RAND_MAX) * INT_MAX);
assert((i & mask) == bit_and(i, mask));
assert((i | mask) == bit_or(i, mask));
assert((~i) == bit_not(i));
assert((i << bit) == bit_shift_left(i, bit));
assert((i >> bit) == bit_shift_right(i, bit));
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment