handeli@ocfmail.ocf.llnl.gov (03/14/91)
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) where a1 and a2 are char arrays ioff1 and ioff2 are bit offsets into the char arrays nbits is the number of bits to move. a1 might be source address and a2 might be destination address. Anybody have such a function?
bharat@cf-cm.computing-maths.cardiff.ac.uk (Bharat Mediratta) (03/14/91)
In article <788@llnl.LLNL.GOV> handeli@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) > >where a1 and a2 are char arrays >ioff1 and ioff2 are bit offsets into the >char arrays >nbits is the number of bits to move. >a1 might be source address and a2 might be >destination address. > >Anybody have such a function? DISCLAIMER: I haven't tested this, but I think it will work. /* * Off1 & Off2 are the offsets of the bit * 0 = rightmost bit. * No error correction */ movebits(src, off1, dest, off2, nbits) int *src, *dest; int off1, off2, nbits; { off1 = 1<<off1; off2 = 1<<off2; while (nbits--) { *dest &= ~off2; /* Zero out the location */ *dest |= ((*src & off1)? 0xFFFF : 0x0000) & off2; /* Yuk */ off2 <<=1; off1 <<=1; } } Cheers! -Bharat -- | Bharat Mediratta | JANET: bharat@cm.cf.ac.uk | +--------------------+ UUNET: bharat%cm.cf.ac.uk%cunyvm.cuny.edu@uunet.uucp | |On a clear disk... | uk.co: bharat%cm.cf.ac.uk%cunyvm.cuny.edu%uunet.uucp@ukc| |you can seek forever| UUCP: ...!uunet!cunym.cuny.edu!cm.cf.ac.uk!bharat |
mouse@thunder.mcrcim.mcgill.edu (der Mouse) (03/15/91)
In article <788@llnl.LLNL.GOV>, handeli@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@larry.mcrcim.mcgill.edu