# PICMicrocontollerMathMethod

## Fixed AN575 INT24 routine (round floating point to 24 bit integer)

I've found also a few more problems with the [AN575] INT24 routine:

1) when AEXP==0, which means zero floating number, but AARGB0:1 is not zero, return will be incorrect. So AARGB0:1 have to be cleared in that case.

2) problem with overflow checking (for example -32769 (0x8e8001) will result in 0xC78e, instead of 0x8000)

There is really something wrong with rounding. They teach in school that if a number is in the middle between two integers, the highest by absolute value is taken. For example, MATLAB has four rounding functions:

```ROUND - round to closest integer (like in school)
FIX - round towards zero (ignore fractional part)
CEIL - round towards plus infinity
FLOOR - round towards minus infinity

let x = [-1:0.25:1]

» x = [-1:0.25:1]
x =
-1 -0.75  -0.5 -0.25     0  0.25   0.5  0.75     1
» round(x)
ans =
-1    -1    -1     0     0     0     1     1     1
» fix(x)
ans =
-1     0     0     0     0     0     0     0     1
» ceil(x)
ans =
-1     0     0     0     0     1     1     1     1
» floor(x)
ans =
-1    -1    -1    -1     0     0     0     0     1
»
```

I assume that the INT24 routine should implement ROUND function. But why there is a check for AARGB1.0 (LSb of integer result)?...

[Here is] a fixed version (I hope) of INT24 routine (fpint.asm).

```#include <p16f84.inc>
cblock 0x20
AEXP ; - exponent 2^(AEXP - 127)
AARGB0
AARGB1 ;- low byte
BEXP
BARGB0
BARGB1	; - temporary for result
TEMPB0
TEMPB1
LOOPCOUNT	; - counter
SIGN
FPFLAGS
endc

mov	macro x, y
movlw x
movwf y
endm

EXP	EQU	AEXP
#define	_C	STATUS, C
#define	_Z	STATUS, Z
#define EXPBIAS	0x7F
#define MSB 0x7
#define LSB 0x0

#define RND 0x0
#define SAT 0x1
#define IOV 0x2

BSF FPFLAGS, RND
BSF FPFLAGS, SAT
;9.4999      8217FF        0009              9
mov 0x82, AEXP
mov 0x17, AARGB0
mov 0xFF, AARGB1
call INT2416
nop
;9.50          821800         000A             10
mov 0x82, AEXP
mov 0x18, AARGB0
mov 0x00, AARGB1
call INT2416
nop
;9.9999       821FFF        000A             10
mov 0x82, AEXP
mov 0x1F, AARGB0
mov 0xFF, AARGB1
call INT2416
nop
;10.50        822800         000A              11
mov 0x82, AEXP
mov 0x28, AARGB0
mov 0x00, AARGB1
call INT2416
nop
;10.999      822FFF        000A               11
mov 0x82, AEXP
mov 0x2F, AARGB0
mov 0xFF, AARGB1
call INT2416
nop
;10.4999     8227FF        000A              10
mov 0x82, AEXP
mov 0x27, AARGB0
mov 0xFF, AARGB1
call INT2416
nop
;11.000      823000         000B              11
mov 0x82, AEXP
mov 0x30, AARGB0
mov 0x00, AARGB1
call INT2416
nop
;11.4999    8237FF        000B              11
mov 0x82, AEXP
mov 0x37, AARGB0
mov 0xFF, AARGB1
call INT2416
nop
;11.50        823800         000C              12
mov 0x82, AEXP
mov 0x38, AARGB0
mov 0x00, AARGB1
call INT2416
nop
;11.999      823FFF        000C              12
mov 0x82, AEXP
mov 0x3F, AARGB0
mov 0xFF, AARGB1
call INT2416
nop
;12.0         824000         000C              12
mov 0x82, AEXP
mov 0x40, AARGB0
mov 0x00, AARGB1
call INT2416
nop
;12.4999    8247FF         000C              12
mov 0x82, AEXP
mov 0x47, AARGB0
mov 0xFF, AARGB1
call INT2416
nop
;12.50       824800          000C              12
mov 0x82, AEXP
mov 0x48, AARGB0
mov 0x00, AARGB1
call INT2416
nop
;12.9999    824FFF         000C              12
mov 0x82, AEXP
mov 0x4F, AARGB0
mov 0xFF, AARGB1
call INT2416
nop
;13.0          825000         000D              13
mov 0x82, AEXP
mov 0x50, AARGB0
mov 0x00, AARGB1
call INT2416
nop
;overflow 32767.5 (RND=1, SAT=1) -> 7FFF
mov 0x8d, AEXP
mov 0x7f, AARGB0
mov 0xff, AARGB1
call INT2416
nop
;overflow -32769 (RND=1, SAT=1) -> 8000
mov 0x8e, AEXP
mov 0x80, AARGB0
mov 0x01, AARGB1
call INT2416
nop
;zero -> 0000
clrf AEXP
call INT2416
nop
;**********************************************************************************************
;       Float to integer conversion
;
;       Input:  24 bit floating point number in AEXP, AARGB0, AARGB1
;
;       Use:    CALL    INT2416         or      CALL    INT24
;
;       Output: 16 bit 2's complement integer right justified in AARGB0, AARGB1
;
;       Result: AARG  <--  INT( AARG ) , RND = 0
;               AARG  <--  ROUND( AARG ), RND = 1
;
;       Max Timing:     2+7+8+9+7+7*6-1+11+2   = 87 clks           RND = 0
;                       2+7+8+9+7+7*6-1+4+11+2 = 91 clks           RND = 1, SAT = 0
;                       2+7+8+9+7+7*6-1+19+2   = 95 clks           RND = 1, SAT = 1
;
;       Min Timing:     2+8+2 = 14 clks
;
;       PM: 61                                  DM: 6
;
;----------------------------------------------------------------------------------------------

INT2416
INT24
RRF             SIGN, F
BSF             AARGB0,MSB		; make MSB explicit

MOVF		EXP,W			; test for zero argument
BTFSS		_Z
GOTO		INT24NOTZERO
INT24CLEAR	CLRF		AARGB0			; if zero, clear AARGB0:1
CLRF		AARGB1			;
RETLW		0x00			; and return
INT24NOTZERO

;check if exponent too high (exp >= 15), i.e. overflow
;Special case when exp == -1 and RND==1 (%1.xxx * 2^-1 = %0.1xxx)

;exp<=-2  AARGB0:1=0
;exp=-1	  AARGB0:1=RND
;exp=0    AARGB0:1>>15
;exp=1    AARGB0:1>>14
;...
;exp=14   AARGB0:1>>1
;exp>=15  overflow (note that +-32768 is treated as overflow even when
;-32768 can fit in 16 bit twos complement form. But -32768 will result
;in correct answer for SAT=1 or 0, although with a set IOV flag)

ADDLW		-EXPBIAS-D'15'		; check if overflow
BTFSC		_C
GOTO            SETIOV16

XORLW		0xFF			; get number of shifts
MOVWF		EXP			; w=-1-(exp-127-15)=14-(exp-127)
ANDLW		0xF0			; clear Z if w > 15
BTFSS		_Z

;do shifts
BCF		_C                      ; first shift
RRF		AARGB0, F
RRF		AARGB1, F
; rounding
BTFSS		EXP, 3			; shift by 8 bits if exp >= 8
GOTO		INT24SHIFTS
RLF		AARGB1, w		; copy bit for rounding
MOVF		AARGB0, w		; shift AARGB0:1 by 8 bits
MOVWF		AARGB1
CLRF		AARGB0

INT24SHIFTS	BCF		EXP, 3			; limit EXP to 0..7 range
INCF		EXP, F			; preincrement EXP
INT24SHIFTSL	BCF		_C			; shift AARGB0:1 right once
RRF		AARGB0, F		; and
RRF		AARGB1, F		; copy bit for rounding
INT24SHIFTTEST	DECFSZ		EXP, F			; repeat if necessary
GOTO		INT24SHIFTSL

SHIFT2416OK     BTFSC           FPFLAGS,RND
BTFSS		_C			; round if next bit is set
GOTO            INT2416OK
INCF		AARGB1,F
BTFSC           _Z
INCF            AARGB0,F

BTFSC           AARGB0,MSB		; test for overflow
GOTO            SETIOV16

INT2416OK       BTFSS           SIGN,MSB                ; if sign bit set, negate
RETLW           0
COMF            AARGB1,F
COMF            AARGB0,F
INCF            AARGB1,F
BTFSC           _Z
INCF            AARGB0,F
RETLW           0

SETIOV16        BSF             FPFLAGS,IOV             ; set integer overflow flag
BTFSS           FPFLAGS,SAT             ; test for saturation
RETLW           0xFF                    ; return error code in WREG

MOVLW		0x80			; saturate to largest two's
MOVWF           AARGB0			; complement 16 bit integer
CLRF		AARGB1			; SIGN = 0, 0x 7F FF
BTFSS           SIGN,MSB		; SIGN = 1, 0x 80 00
COMF		AARGB0, F
BTFSS           SIGN,MSB
COMF		AARGB1, F
RETLW           0xFF                    ; return error code in WREG
;**********************************************************************************************

```

 file: /Techref/microchip/math/round/fp-24bint-ng.htm, 8KB, , updated: 2011/1/26 13:15, local time: 2022/8/13 20:39, TOP NEW HELP FIND:  44.197.230.180:LOG IN

 ©2022 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?Please DO link to this page! Digg it! / MAKE! PIC Microcontoller Math Method

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type a nice message (short messages are blocked as spam) in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.

Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
 Did you find what you needed? "No. I'm looking for: " "No. Take me to the search page." "No. Take me to the top so I can drill down by catagory" "No. I'm willing to pay for help, please refer me to a qualified consultant"

.