Newsgroups: comp.lang.perl Path: utzoo!utgpu!watserv1!watdragon!rose!ccplumb From: ccplumb@rose.uwaterloo.ca (Colin Plumb) Subject: Re: Even Parity Table Generation Message-ID: <1991Feb13.205348.2779@watdragon.waterloo.edu> Sender: daemon@watdragon.waterloo.edu (Owner of Many System Processes) Organization: University of Waterloo References: <121817@uunet.UU.NET> Date: Wed, 13 Feb 1991 20:53:48 GMT Lines: 51 rbj@uunet.UU.NET (Root Boy Jim) wrote: >I needed an even parity table, so I decided to generate it recursively. >I thought people might be interested in my solution, and or >commenting on how it might be done better. And while I'm at it, >I hereby request another function: chr(), the opposite of ord(). >Either that, or get rid of ord. Anyway, here it is: Yes, I'd like chr() (or whatever someone wants to call it), too. Anyway, there's a simple iterative way to generate bit-couting tables, parity tables, etc. bits[0] = 0; for (i = 1; i < 256; i++) bits[i] = bits[i>>1] + (i&1); For your parity application, it's just: even[0] = 0; for (i = 1; i < 128; i++) even[i] = i + ((even[i>>1]&128) ^ (i & 1 ? 128 : 0)); There are various tricky ways of rewriting that last line. I think even[i] = i + (128 & (-(i & 1) ^ even[i>>1])); is rather fun on a non-sign-magnitude machine. In (untested) perl, that becomes: sub mkEven # global %even { local($i); $even{"\0"} = "\0"; for $i (1..127) { $even{pack('c',$i)} = pack('c',$i + (($i & 1) ? 128 : 0) ^ (128 & $even{pack('c',$i>>1)})); } } Well, okay, it's hideous... Using a temporary array, sub mkEven # global %even { local($i,@even); $even[0] = 0; $even{"\0"} = "\0"; for $i (1..127) { $even[$i] = ((i & 1) << 7) ^ $even[$i >> 1]; $even{pack('c',$i)} = pack('c', $i + $even[$i]); } } -- -Colin