[net.lang.mod2] Bit stripping

haynes@DECWRL.DEC.COM (Charles Haynes) (08/05/86)

Stripping high order bits via the MOD operator is neither fast nor reliable.

Unfortunately, modula-2 implementations differ on whether ORD(ch) can be
negative or not, and how MOD operates on negative numbers. Secondly, MOD is
usually equivalent to divide in cost, though many compilers optimize for DIV
and MOD by powers of two.

Mike Powell's modula-2 provides a module called "BitOperations" that will let
you do bit AND, which would be fine, or in many cases an IF would be
reasonable. IE. 

IF ORD(ch) >= 128 THEN ch := CHR(ORD(ch)-128); END;
 
or

IF ORD(ch) < 0 THEN ch := CHR(ORD(ch)+128); END;

If you are willing to use machine dependent code, instead of reading into a
buffer of chars, you could read into an array of things which looked like:

BitChar = RECORD parity: BOOLEAN; ch: [0..127]; END;

Then use the ch fields, this assumes your modula-2 compiler allows some kind
of bit level control of record layout. Warning: this kind of code can often
be slower than the naive "IF" statement used above. Know what you are doing!

	-- Charles

joel@decwrl.UUCP (08/05/86)

Yet another way to accomplish stripping off the parity bit is using set
arithmetic.

ch := char(bitset(ch) * bitset{0..6}))

Of course, this may not generate great code either.  Mike Powell's compiler
for the VAX generates an extra mcoml instruction on the constant 127, rather
than complementing at compile-time.  (No AND instruction, just an AND NOT
instruction on the VAX.)

-- 
- Joel McCormack {ihnp4 decvax ucbvax allegra}!decwrl!joel
		 joel@decwrl.arpa

treid@MITRE.ARPA (Thomas Reid) (08/05/86)

I mad thought to add to the bit stripping problem (nee, opportunity).
The subject of machine dependence arose - a solution?:  Put each possible
machine interpretation in a case statement in a procedure in a module.
Then use the initialization section of the module to test which of the
possible cases are present for this execution and set the proper case
selector (of course, a static variable inside the module).  Overhead?
The initialization is executed only once, so basically just the overhead
of the case - order the case in order of likelihood and might be small.

A clever idea what?  Have the initialization test for machine dependence

ken@ROCHESTER.ARPA (Comfy chair) (08/05/86)

This is just an idea and probably should only be practiced by
expert programmers under supervision :-), but how about using
BITSETs and conversion operators? Something like:

	s := BITSET(ch) * {0,1,2,3,4,5,6};
	ch := CHAR(s);

Forgive me if I forgot the right syntax. Anyway this is also an
excuse to try to weed out bad mail addresses with a test message.
Thank you for your patience. I hope you enjoy the forum as much
as I enjoy administering it.

	Cheers, Ken
	Info-Modula-2-request

As always, meta-mail should go to info-modula-2-request.