Radice e Log
© by Vittorio Crapella - i2viu
© by Vittorio Crapella - i2viu
Dalla seguente richiesta : " Dovrei far effettuare il calcolo del logaritmo in base 10 di un numero ad un ST 62xx ...ma non so come fare ..", é nato il seguente listato assembler:
;LOGARITMO DI UN NUMERO COMPRESO TRA 10 e 65536 ;Versione 29-05-1999 By Vittorio Crapella;SI ENTRA CON IL NUMERO IN DUE BYTE MSB e LSB;SI ESCE CON RISULTATO MOLTO APPROSSIMANTO IN TRE BYTE B1,B2B3 ;B1=unitalog;B2=decimlog;B3=centelog;VARIABILI USATE:;msb byte + significativo del numero ;lsb byte - significativo del numero;rismsb byte risutato + sign.;rislsb byte risutato - sign.;unitalog unita logaritmo del numero;decimlog decimi " " ";centelog centesimi " " "; Esempio: MSB+LSB = unitalog,decimlog centelog; log 742 = 02h+E6h = 2, 8 7 ;cioé unitalog =2 decimlog =8 centelog=7 logari ldi wdog,254 ld a,msb jrnz clw ;se il numero minore di 10 ld a,lsb ;non fa il logaritmo cpi a,10 jrnc clw retclw clr wdivi ldi wdog,254 ;carico wdog clr rismsb ;azz. byte risultato MSB clr rislsb ;azzeramento risultato LSBldn1 ld a,msb ;carico nel reg a il byte + significativo jrnz div ;se non e` zero salto ld a,lsb ;altrimenti prendo byte - significativo jrnz jpan jp incunjpan ld w,a jp ancora ;e vado a dividere div ld a,lsb ;prendo il byte - signif.suba ldi wdog,254 subi a,10 ;sottraggo 10 al numero jrc decn1 inc rislsb jrnz jpsu inc rismsbjpsu jp suba ;se a>= 10 continuo a sottrarre e inc risultatodecn1 inc rislsb dec msb ;chiedo riporto al byte + significativo jrnz jpsu ;e se MSB non e` zero continuo a sottrarreancora ldi wdog,254 subi a,10 ;sottraggo ancora jrc ok ;se vado sotto 0 cio` 255 o meno jrz okk_ ;anche se 0 salto inc rislsb ;incremento ancora il risultato jrnz jpan_ inc rismsbjpan_ jp ancora ;e continuo fino a che 10 > del numerookk_ inc rislsbok ld a,rislsb ld lsb,a ld a,rismsb ld msb,a incun inc unitalog ;conta quante div. x 10 ld a,lsb cpi a,10 jrc ldaw ;se > 10 divide ancora ld w,a jp divildaw ld a,w ;prende nr prima dell'ultima div x 10 cpi a,10 jrnz cp15 clr decimlog ;il log e` solo intero senza decimali clr centelog ;per i numeri 10 100 1000 10000 retcp15 cpi a,16 ;se >= 16 salta jrnc cpi84 subi a,4 jp caldivcpi84 cpi a,85 jrc addi15 ;se minore di 84 +15 jp piu10 ;altrimenti +10addi15 addi a,15caldiv clr decimlog ;divide per dieci ldi wdog,255 cpi a,10 ;se a minore 10 salta jrc ok_sub_ subi a,10 inc decimlog ldi wdog,255 cpi a,10 jrnc sub_ok_ ld centelog,a ret ;FINEpiu10 cpi a,89 jrc ad10 ;se minore 89 allora +10add5 addi a,5 ;altrimenti solo +5 cpi a,100 jrc jpcal ldi a,99jpcal jp caldiv ;divide e trova decimaliad10 addi a,10jpca jp caldivSono graditi commenti, miglioramneti o quant'altro per ridurre le approssimazioni del risultato.
;RADICE QUADRATA PER NUMERI DA 1 A 16129;SI ENTRA CON IL NUMERO IN 2 BYTE MSB-LSB;SI ESCE CON IL RISULTATO NEL REGISTRO a;Vers. 12-08-99 by i2viusqr clr y ;usato per il risultato ld a,lsb ldi x,1cpax cp a,x ;verifica se a è = o > di x jrnc subax ;se sì salta dec msb ;altrienti prestito da MSB inc msb ;se non è zero jrz rest ;se MSB=0 fine e salta dec msbsubax sub a,x ;sottrae x da a inc y ;conta il numero di volte, sarà il risultato inc x ;rende x un numero dispari in aumento inc x jp cpax ;continua a sottrarre numeri dispari rest ld resto,a ;ha finito pertanto mette a nel resto ld a,y ;in a il risultato=y e ritorna retvedi atro metodo