Radice e Log

© by Vittorio Crapella - i2viu

LOGARITMO IN BASE 10 CON MICRO ST62XX


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
  ret
clw  clr  w
divi  ldi     wdog,254  ;carico wdog
  clr  rismsb    ;azz. byte risultato MSB
  clr  rislsb    ;azzeramento risultato LSB
ldn1  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  incun
jpan  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  rismsb
jpsu  jp  suba    ;se a>= 10 continuo a sottrarre e inc risultato
decn1  inc  rislsb
  dec  msb        ;chiedo riporto al byte + significativo
  jrnz  jpsu     ;e se MSB non e` zero continuo a sottrarre
ancora  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  rismsb
jpan_  jp  ancora    ;e continuo fino a che 10 > del numero
okk_  inc  rislsb
ok  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  divi
ldaw  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
  ret
cp15  cpi  a,16    ;se >= 16 salta
  jrnc  cpi84
  subi  a,4
  jp  caldiv
cpi84  cpi  a,85
  jrc  addi15    ;se minore di 84 +15 
  jp  piu10    ;altrimenti +10
addi15  addi a,15
caldiv  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      ;FINE
piu10  cpi  a,89  
  jrc  ad10         ;se minore 89 allora +10
add5  addi  a,5    ;altrimenti solo +5
  cpi  a,100
  jrc  jpcal
  ldi  a,99
jpcal  jp  caldiv    ;divide e trova decimali
ad10  addi  a,10
jpca  jp  caldiv

Sono graditi commenti, miglioramneti o quant'altro per ridurre le approssimazioni del risultato.

RADICE QUADRATA CON MICRO ST62XX

;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 i2viu

sqr  clr  y  ;usato per il risultato
  ld  a,lsb
  ldi  x,1
cpax  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  msb
subax  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
  ret
vedi atro metodo