piclist 2001\04\08\051310a >
Thread: Rounding to closest 1's multiple, code enclosed :)
www.piclist.com/techref/microchip/devices.htm?key=pic
flavicon
face BY : Nikolai Golovchenko email (remove spam text)



Thanks Bob an Scott! Great ideas.

Scott, your version can be improved a little, by 2 words:

{Quote hidden}

The above does the same as:

   movf L, w
   addwf M, w
   skpnc
    addlw 1
   addwf H, w
   skpnc
    addlw 1
   movwf temp, w


Here is a further extension. It is possible to get directly the modulo
10 value, without going through the modulo 5 phase. Unfortunately, not
much difference in code size - 27 words.

For what it's worth:

;Nibble weights and modulo 10 values:
;1 % 10 = 1     | L (low byte)
;16 % 10 = 6    |
;256 % 10 = 6       | M (middle byte)
;4096 % 10 = 6      |
;65536 % 10 = 6         | H (high byte)
;1048756 % 10 = 6       |

   movf H, w           ;add middle and high bytes (256%10=6, and 65536%10=6)
   addwf M, w
   skpnc               ;if carry ((256*6)%10=6),
    addlw 1            ;increment w - this is equivalent to adding 6,
                       ;because w is to be multiplied by 6
   movwf temp          ;add nibbles ((1*6)%10=6, (16*6)%10=6)
   swapf temp, w
   addwf temp, f
   skpndc              ;if digit carry, increment
    incf temp, f
   swapf L, w          ;add higher nibble from low byte (16%10=6)
   addwf temp, w
   skpndc
    addlw 1
   movwf temp          ;store in temp.
                       ;Now temp should be multiplied by 6. The lower 4 bits
                       ;will have the following weights after multiplication:
                       ;1*6 = 6
                       ;2*6 = 12
                       ;4*6 = 24
                       ;8*6 = 48
                       ;That can be simplified if we apply the modulo 10 operation:
                       ;6%10 = 6 = 1 + 5
                       ;12%10 = 2
                       ;24%10 = 4
                       ;48%10 = 8
                       ;If we add 5 when lower bit is set, we get a corrected value,
                       ;which can be used then directly, without multiplication!

   btfsc temp, 0       ;correct sum
    addlw 5
   skpndc              ;if we get here skipping addition, the DC flag is cleared previously
    addlw 6            ;if nibble overflows, add 6 (16%10 = 6)

   addwf L, w          ;add lower nibble of low byte (weight = 1)
   skpndc              ;fix overflows
    addlw 6
   skpndc              ;one more time (e.g. if sum was 31, it overflows again
    addlw 6            ;after 15+6=21=16+5, and should be corrected again 5+6=11)

   addlw -10           ;find modulo 10 of a 4 bit number
   skpdc
    addlw 10

   andlw 0x0F          ;clear higher bits (if necessary)


Best regards,
Nikolai

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics


<5112902826.20010408121103@yahoo.com> 7bit

In reply to: <Pine.LNX.4.21.0104070957080.24639-100000@tempest2.blackhat.net>
See also: www.piclist.com/techref/microchip/devices.htm?key=pic
Reply You must be a member of the piclist mailing list (not only a www.piclist.com member) to post to the piclist. This form requires JavaScript and a browser/email client that can handle form mailto: posts.
Subject (change) Rounding to closest 1's multiple, code enclosed :)

month overview.

new search...