> Here is the code that Scott Dattalo posted, very fast and clean. And here is the code Ray posted... > DIV3 > ; Call with 8bit in W , exit with X/3 in W > ; > ; RAM: uses T and Xh:Xl > ; Here's another routine that does the job just ever so slightly faster. (And it's been tested). It takes advantage of the often forgotten Digit Carry flag. ; Divide by 3 ; Input in W , Output W/3 ; ADDLW 1 SKPNC RETLW 0x55 MOVWF quo_L CLRF quo_H RLF quo_L,F RLF quo_H,F RLF quo_L,F RLF quo_H,F ;quo_L:H = 4*dividend ADDWF quo_L,F SKPNC INCF quo_H,F ;quo_L:H = 5*dividend ;At this point, we have dividend * 5. We actually need ;dividend * 0x55. So the next instructions will add ;add 0x10*quo_L:H to quo_L:H. SWAPF quo_H,W ;quo_H * 0x10 ADDWF quo_H,F ;quo_H += quo_H*0x10 SWAPF quo_L,W ;quo_L * 0x10 ANDLW 0x0f ; ADDWF quo_L,F ;quo_L += quo_L*0x10 SKPNDC ;Note the 'DC' ADDLW 1 ; ADDWF quo_H,W ;quo_H += quo_L*0x10 (plus stuff) 19 cycles/instructions It works on the same 'multiply by 0x55 and divide by 0x100' concept. It's kind of interesting to see how much error is incurred by this method. If you simply multiply by 0x55 and divide by 0x100 you'll discover that the result is often too low. That can be explained by the fact that an infinite series has been truncated. Or equivalently, 85/256 = 0.3320 and 1/3 = 0.33333... So my implementation of the algorithm has a slight modification: n/3 ~ (n+1)*85/256 To see if this really works, you can either test by brute force all 256 values of n (yeah, that's what I did at first) OR try to find a relationship that proves the approximation is valid. So in the spirit of my recently purchased 3rd edition of Knuth's 'Art of Computer Programming: Seminumerical Algorithms'(*), I thought it would be interesting to try the proof thingy. (*) See http://www-cs-faculty.stanford.edu/~knuth/taocp.html for info on Knuth's books. Recall John Halleck's post on integer division: (a integerdivide b) = (a-(a mod b))/b (Note that there was a slight typo [as opposed to a thinko] in John's post) Or in C jargon: = (a -(a % b)) /b And since I'm interested in the error, I want to find the result of : e = (n integerdivide 3) - ( (n+1)*85 integerdivide 256) where e = the error in the algorithm n = input between 0 and 255 e = (n - (n%3))/3 - ( (n+1)*85 - ((n+1)*85 % 256))/256 = n/3 - (n+1)*85/256 - (n%3)/3 + ((n+1)*85 % 256) /256 256*n - 255*(n+1) -256*(n%3) + 3*(((n+1)*85)%256) = ----------------- + -------------------------------- 768 768 mod identity: c*(a%b) = (a*c) % (b*c) n - 255 -((256*n)%768 + ((n+1)*255)%768) e = ------- + ----------------------------------- 768 768 n - 255 (-n + 255) % 768 e = ------- + ---------------- (**) 768 768 n - 255 - (n - 255) % 768 e = -------------------------- 768 Now, since the input, n, is between 0 and 255, the mod term in the numerator: (n - 255) % 768 = n - 255 and so the error is e = 0 ! In fact, the approximation is exact for all values of n between -512 and 1023 (**) In general, a % c + b % c != (a+b) % c. However, in this case, the difference always results in an integer that's less than 768. Lucky. Scott