Myke Predko accidentally sent this message to me directly; I'm forwarding it to the whole list. -Andy ------- Forwarded Message Follows ------- Date: Wed, 8 Jan 97 10:15 EST To: fastfwd@ix.netcom.com From: myke@passport.ca (myke predko) Subject: Re: A New Challenge >It's been a while since I've posted a programming challenge here, >so here's one with which to start the new year: > > File-register REG contains a number between 0 and 127, inclusive. > The W-register contains a number between 0 and 127, inclusive. > > Write the most efficient PIC16C54 program that you can, using as > few additional file registers as possible, to calculate: > > (REG xor W) + 2 * (REG and W) > > The result may end up in either W or REG; it doesn't matter. Aha! A challenge (pronounced "shallange" with a high affected french accent)! Before starting to code, I decided that I would want to reduce this as much as possible. Bitwise XOR can be represented as: A ^ B = ( A | B ) - ( A & B ) I don't remember if I saw this in a book somewhere, but I *think* it is true (at least it worked for all my test cases). If it's not, then in the immortal words of Emily Latella, "Never Mind". If it is, then we can start substituting in the formula: ( w ^ Reg ) + 2 * ( w & Reg ) = ( w | Reg ) - ( w & Reg ) + 2 * ( w & Reg ) = ( w | Reg ) - ( w & Reg ) + ( w & Reg ) + ( w & Reg ) = ( w | Reg ) + ( w & Reg ) Which seems to be true when I work it through a bunch of cases on my calculator. Going over it, the condition Andy puts in about the numbers having to be only 7 bits long makes sure it works properly in the 8 bit PIC. Coding this is pretty trivial and I would probably use the following solution that uses two extra registers: movwf Save_w ; Save "w" for the Second calculation iorwf Reg, w ; Do the first calculation movwf Result ; Save the first calculation to be added with movf Save_w, w ; Do the Second Calculation andwf Reg, w addwf Result[, w] ; Add the two together and store wherever Or, If you only had one extra Register to play with: movwf Result ; Save "w" for the Second Calc iorwf Reg, w xorwf Result ; Swap Result & "w" xorwf Result, w xorwf Result andwf Reg, w ; Do Second Calculation addwf Result[, w] ; Add to two together and save wherever Now, is there any way in which to reduce (w|Reg)+(w&Reg)? myke > >-Andy > >=== Andrew Warren - fastfwd@ix.netcom.com === >=== Fast Forward Engineering - Vista, California === >=== === >=== Custodian of the PICLIST Fund -- For more info, see: === >=== http://www.geocities.com/SiliconValley/2499/fund.html === > > "There are only three kinds of economists in the world. Those who can count and those who can't." - Eddy George, governor of the Bank of England