bit mover
der Mouse
mouse at thunder.mcrcim.mcgill.edu
Fri Mar 15 20:42:17 AEST 1991
In article <788 at llnl.LLNL.GOV>, handeli at ocfmail.ocf.llnl.gov writes:
> I need a C function which can move arbitrary bits around from one
> memory location to another with a bit offset of anything. For
> example, the call might look like
> movebits(a1,ioff1,a2,ioff2,nbits)
This really belongs in a C group. I have cross-posted to comp.lang.c
and am redirecting followups there.
I am assuming that the bits in a byte are taken LSB-first, so that an
offset of 9, for example, skips the first byte and the LSB of the
second byte. To switch this, fiddle with some of the shift operations.
Warning: untested. Assumes that the number of bits in an unsigned int
is no less than one less than twice the number of bits in an unsigned
char (most machines will have no trouble with this restraint).
Optimization possibilities abound.
#define CHAR_BITS 8 /* or whatever: # of bits in unsigned char */
movebits(a1,ioff1,a2,ioff2,nbits)
unsigned char *a1; /* from */
unsigned int ioff1;
unsigned char *a2; /* to */
unsigned int ioff2;
unsigned int nbits;
{
unsigned int buf;
unsigned char mask;
int have;
if (nbits < 1) return; /* careful: don't read *a1 in this case */
a1 += ioff1 / CHAR_BITS;
ioff1 %= CHAR_BITS;
a2 += ioff2 / CHAR_BITS;
ioff2 %= CHAR_BITS;
buf = *a1++;
have = CHAR_BITS - ioff1;
buf >>= ioff1;
while (nbits > 0)
{ if ((have < CHAR_BITS) && (nbits > have))
{ buf |= *a1++ << have;
have += CHAR_BITS;
}
if (ioff2+nbits < CHAR_BITS)
{ mask = ((1 << nbits) - 1) << ioff2;
}
else
{ mask = (~0) << ioff2;
}
*a2 = (*a2 & ~mask) | ((buf << ioff2) & mask);
a2 ++;
buf >>= CHAR_BITS - ioff2;
have -= CHAR_BITS - ioff2;
nbits -= CHAR_BITS - ioff2;
ioff2 = 0;
}
}
der Mouse
old: mcgill-vision!mouse
new: mouse at larry.mcrcim.mcgill.edu
More information about the Comp.unix.questions
mailing list