=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Date: Fri, 25 Feb 2000 09:26:18 From: Nikolai Golovchenko To: pic microcontroller discussion list Subject: Re: fast % routine -------------------------------------------------------------------------------- Nice done, Scott! To add, if Tony needs a little better precision (especially for higher values of input byte), one more term should be added, so that d = (((h >> 3 + h) >> 3 + h) >> 1 + h) >> 2 = h * (1/4 + 1/8 + 1/64 + 1/512) This adds only 6 cycles, and reduces errors from 51 to 11 cases per all combinations of input (in both routines absolute errors are small, +-1). > MOVWF temp ;Hex value is in W. > CLRC ;Clear the Carry bit so it doesn't affect RRF RRF temp,F CLRC RRF temp,F CLRC RRF temp,F ADDWF temp, F > RRF temp,F > CLRC > RRF temp,F > CLRC > RRF temp,F ;temp = h>>3 > ADDWF temp,F ;temp = h + (h>>3) > RRF temp,F ;temp = (h + (h>>3)) >> 1 > ADDWF temp,F ;temp = h + ((h + (h>>3)) >> 1) > RRF temp,F > CLRC > RRF temp,W ;d = W = (h + (h + (h>>3)) >> 1) >> 2 > RETURN Nikolai On Friday, February 25, 2000 Scott Dattalo wrote: > On Fri, 25 Feb 2000, Tony Nixon wrote: >> Hi all, >> >> I need a fast 0 - 255 -> % routine >> >> Eg Byte value = 89 >> % value = 34 >> >> 89 / 255 * 100 >> >> I did this routine - any others?? >> >> Value in W on entry >> Result in PcntH on return >> >> ToPcnt movwf PCntH > > You mean like this: > ;******************************************************************* > ;scale_hex2dec > ; The purpose of this routine is to scale a hexadecimal byte to a > ;decimal byte. In other words, if 'h' is a hexadecimal byte then > ;the scaled decimal equivalent 'd' is: > ; d = h * 100/256. > ;Note that this can be simplified: > ; d = h * 25 / 64 = h * 0x19 / 0x40 > ;Multiplication and division can be expressed in terms of shift lefts > ;and shift rights: > ; d = [ (h<<4) + (h<<3) + h ] >> 6 > ;The program divides the shifting as follows so that carries are > automatically > ;taken care of: > ; d = (h + (h + (h>>3)) >> 1) >> 2 > ; > ;Inputs: W - should contain 'h', the hexadecimal value to be scaled > ;Outputs: W - The scaled hexadecimal value is returned in W > ;Memory: temp > ;Calls: none > scale_hex2dec > MOVWF temp ;Hex value is in W. > CLRC ;Clear the Carry bit so it doesn't affect RRF > RRF temp,F > CLRC > RRF temp,F > CLRC > RRF temp,F ;temp = h>>3 > ADDWF temp,F ;temp = h + (h>>3) > RRF temp,F ;temp = (h + (h>>3)) >> 1 > ADDWF temp,F ;temp = h + ((h + (h>>3)) >> 1) > RRF temp,F > CLRC > RRF temp,W ;d = W = (h + (h + (h>>3)) >> 1) >> 2 > RETURN > ? > Scott