Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC16F628 Rounding result of division?

Status
Not open for further replies.

Zasurus

New Member
Hi,
I am fairly new to this and feel like I am getting somewhere will most things but the Maths functions! I have found loads of functions on piclist.com like * and / but can't work out a quick(ish) way to round the 24bit result of my division?

For example I have a result of a division = 25.658
so the function I have got from piclist is great and gives me two numbers the first is the result = 25 and the other is the remainder = 658 (everything after the decimal place). But I can't find anywhere with a function to tell me if a 24bit remainder is > 55555555 etc...

HELP! PLEASE! :D

Thanks!
 
Before the division add the equivalent of 0.0005 * the number you are dividing by. If this doesn't work then you need to post more information.

Mike.
 
Pommie said:
Before the division add the equivalent of 0.0005 * the number you are dividing by. If this doesn't work then you need to post more information.

Mike.

Thanks for the quick reply. :D
I don't think I understand what you mean? How can I * by 0.0005 as that is not a integer? :confused:
Here is an example of my code to divide two values that I want to round up/down depending on the remainder:

Thanks again! :eek:

Code:
;-------------------------
;Divide:
; 15900/1600 = 9.9375
; so round up to 10
;-------------------------
   ;15900
    MOVLW   d'28'
    MOVWF   nratorL
    MOVLW   d'62'
    MOVWF   nratorM
    CLRF    nratorH

   ;1600
    MOVLW   d'6'
    MOVWF   denomL
    MOVLW   d'64'
    MOVWF   denomM
    CLRF    denomH

    CALL    Divide_24x24

   ;Result:           nratorH  nratorM  nratorL
   ;Remainder:        remainH  remainM  remainL
;-------------------------

;-------------------------
;Divide:
; 15000/1600 = 9.375
; so round down to 9
;-------------------------
   ;15900
    MOVLW   d'152'
    MOVWF   nratorL
    MOVLW   d'58'
    MOVWF   nratorM
    CLRF    nratorH

   ;1600
    MOVLW   d'6'
    MOVWF   denomL
    MOVLW   d'64'
    MOVWF   denomM
    CLRF    denomH

    CALL    Divide_24x24

   ;Result:           nratorH  nratorM  nratorL
   ;Remainder:        remainH  remainM  remainL
;-------------------------





;--------------------------------------------------------------------
; SUBROUTINE - 24 BIT DIVISION  from  TONY NIXON
; numerator:        nratorH  nratorM  nratorL
; denominator:      denomH   denomM   denomL
;
; result:           nratorH  nratorM  nratorL
; remainder:        remainH  remainM  remainL
;--------------------------------------------------------------------
Divide_24x24:
;--------------------------------------------------------------------
      movlw     d'24'      ; set decimal 24 loop count
      movwf     BCount
      movf      nratorH,w ; copy Numerator into Shift Holding ram registers (w-reg)
      movwf     shiftH
      movf      nratorM,w
      movwf     shiftM
      movf      nratorL,w
      movwf     shiftL
      clrf      nratorH   ;  clear final Answer Numerator Ram locations
      clrf      nratorM
      clrf      nratorL
      ;
      clrf      remainH  ;  clear final Answer Remainder Ram locations
      clrf      remainM
      clrf      remainL
dloop:
      bcf       STATUS, C  ; bit clear Carry Flag in STATUS register
      rlf       shiftL, f  ; Shift numerator(dividend) Left to move
      rlf       shiftM, f  ; next bit to remainder
      rlf       shiftH, f  ; and shift in next bit of result

      rlf       remainL, f ; shift carry (next Dividend bit) into remainder
      rlf       remainM, f
      rlf       remainH, f
      movf      denomH,w
      subwf     remainH,w  ; subtract divsor(denomH) from(newly shifted left) Remainder HIGH byte.
      btfss     STATUS, Z
       goto     nochk        ; skip if result was ZERO from good subtraction result
      ;
      movf      denomM,w
      subwf     remainM,w  ; subtract divsor(denomM) from(newly shifted left) Remainder MIDDLE byte.
      btfss     STATUS, Z
       goto     nochk        ; skip if result was ZERO from good subtraction result
      ;
      movf      denomL,w
      subwf     remainL,w  ; subtract divsor(denomL) from(newly shifted left) Remainder LOW byte.
nochk:
      btfss     STATUS, C   ;  Carry SET? then denom is larger than reemainder
      goto      nogo
      ;
      movf      denomL,w          
      subwf     remainL, f       ; Subtract denominator from remainder value in Low Byte
      btfsc     STATUS, C       ; Carry Set? Then execute fixup code for when a borrow is generated
       goto     nodec_remainM   ; when no borrow bit is needed from the higher byte positions.
      decf      remainM, f      ; Decrement to Borrow from Middle Byte, because carry was SET.
      movf      remainM,w
      xorlw     0xff             ; Check if rollover from Borrow occurred. remainM value went from 0 to 0xFF 
      btfsc     STATUS, Z
       decf     remainH, f       ; ZERO bit set, yes rollover, so Decrement to Borrow from High Byte, too!
nodec_remainM:
      movf      denomM,w
      subwf     remainM, f       ; Subtract denominator from remainder value in Middle Byte
      btfss     STATUS, C
       decf     remainH ,f      ; Decrement High Byte, to borrow 1 bit
      movf      denomH,w          
      subwf     remainH, f      ; Subtract denominator from remainder value in High Byte
      bsf       STATUS, C       ; set CARRY bit to rotate in Numerator Result next.
nogo:
      rlf       nratorL, f  ; rotate Numerator result left 1 bit
      rlf       nratorM, f
      rlf       nratorH, f
      decfsz    BCount, f   ; decrement the Loop Bit Counter
       goto     dloop
      ;
      return                 ; all done
;--------------------------------------------------------------------------------
 
Sorry, I assumed you wanted to round the last digit.

For what you are doing, 15900/1600 = 9.9375, you can add half the divisor and just do the integer part. (15900+800)/1600 = 10.4375. Alternatively, after the integer divide you can check bit 7 of remainH - if it's set then increment the integer answer.

@Mike, I suspect this is what you were going to suggest.

Mike.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top