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 RLF AARGB0, W ; save sign in SIGN.7 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 GOTO INT24CLEAR ; jump to clear AARG ;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 GOTO INT24SHIFTTEST ; jump to decrement and zero check 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: 2024/10/4 02:01,
3.238.82.77:LOG IN ©2024 PLEASE DON'T RIP! THIS SITE CLOSES OCT 28, 2024 SO LONG AND THANKS FOR ALL THE FISH!
|
©2024 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? <A HREF="http://piclist.com/techref/microchip/math/round/fp-24bint-ng.htm"> PIC Microcontoller Math Method </A> |
Did you find what you needed? |
PICList 2024 contributors:
o List host: MIT, Site host massmind.org, Top posters @none found - Page Editors: James Newton, David Cary, and YOU! * Roman Black of Black Robotics donates from sales of Linistep stepper controller kits. * Ashley Roll of Digital Nemesis donates from sales of RCL-1 RS232 to TTL converters. * Monthly Subscribers: Gregg Rew. on-going support is MOST appreciated! * Contributors: Richard Seriani, Sr. |
Welcome to piclist.com! |
.