2.3.4.4.2. Conversión Binario->Decimal

Esta función, complementaria de la anterior, nos permite hacer laconversión en sentido inverso, partiendo de un valor binario yconvirtiéndolo en decimal.
Aunque lo más probable es que el tipo de entrada del dato seanumérico, hemos diseñado una función como filtro deentrada que analizará mediante un COND las posibles entradas admitiendolistas y cadenas y rechazando cualquier otro tipo de dato.
en caso de que el dato no sea de uno de estos tres tipos admitidos, seimprimirá un mensaje de error. Si el dato es admitido pero no es decarácter binario (incluye términos distintos de cero óuno, la función devolverá NIL.

;;;DECIMAL.LSP
;;;Recibe un número binario y lo convierte en decimal
;;;debe comprobar el tipo de dato recibido,
;;;que puede ser cadena, número o lista
;;;
;;;Función utilitaria BIT
;;;devuelve el valor decimal del bit en la posición recibida:
;;;
(defun Bit (pos) (lsh 1 (1- pos)))
;;;
;;;
;;;Función utilizada como acumulador del valor de la posición:
;;;
(defun PosBit ()
(if (null posicion)
(setq posicion 1)
(setq posicion (1+ posicion))
) ;_ fin de if
) ;_ fin de defun
;;;
;;;PREDICADOS DEFINIDOS PARA ESTA FUNCIÓN:
;;;Como filtro de entrada se emplean tres predicados
;;;definidos expresamente para ella:
;;;STRINGP, STD-DOTTED-PAIR-P y BINARIOP
;;;
;;;Predicado STRINGP
;;;Comprueba si el dato es una cadena
;;;(ver PREDICADOS DEFINIDOS POR EL USUARIO)
;;;
(defun stringp (dato) (equal (type dato) 'STR))
;;;
;;;Predicado STD-DOTTED-PAIR-P
;;;Comprueba de que se trate de un par punteado:
;;;Adaptado de la Standard Lisp Library
;;;de Reini Urban:
;;;
(defun STD-DOTTED-PAIR-P (lst)
(and (vl-consp lst) (not (listp (cdr lst))))
) ;_ fin de defun
;;;
;;;Predicado Binariop
;;;Comprueba que la lista incluya valores sólo 0 ó 1
;;;
(defun Binariop (numbin /)
(apply 'and
(mapcar '(lambda (term) (or (equal term 0) (equal term 1)))
numbin
) ;_ fin de mapcar
) ;_ fin de apply
) ;_ fin de defun
;;;
;;;Función utilitaria NUMLISTA
;;;Recibe cualquier número decimal y devuelve los dígitos aislados
;;;en formato de lista
;;;Si el número es real, lo trunca despreciando los decimales
;;;
(defun Numero->Lista (numero / lista)
(while (> numero 0)
(setq lista (cons (rem (fix numero) 10) lista))
(setq numero (/ (fix numero) 10))
) ;_ fin de while
lista
) ;_ fin de defun
;;;
;;;Función utilitaria Cadena->Lista
;;;Recibe una cadena de caracteres y devuelve los caracteres
;;;aislados en formato de lista
;;;
(defun Cadena->Lista (cadena)
(mapcar
'chr ;3.- convierte los códigos ASCII
; a caracteres

(vl-string->list ;2.- convierte la cadena a lista
; de códigos ASCII

cadena
) ;_ fin de vl-string->list
) ;_ fin de mapcar
) ;_ fin de defun
;;;
;;;Función ConvierteDecimal
;;;Realiza la conversión, al ser la evaluación siempre de izquierda a derecha,
;;;debe invertir la lista para iniciar la comprobación por el bit último de la
;;;derecha.

;;;Esta comprobación se hace mediante el mapeado de una función LAMBDA a la
;;;lista,
que comprueba si el número es cero y en caso que no lo sea, inserta
;;;el valor
decimal del bit en la lista.
;;;Una vez concluido este mapeado, se le aplica la funcióm '+ para sumar todos
;;;los valores, con lo que obtenemos el resultado de la conversión
;;;Binario->Decimal.

;;;Devuelve un número decimal
;;;
(defun ConvierteDecimal (numbin / posicion)
(if (Binariop numbin)
(apply
'+ ; suma los valores de la lista
; devuelta por MAPCAR

(mapcar
(function
(lambda (x)
(PosBit) ;5.- valora la variable posicion
(if (not (zerop x))
(bit posicion)
0 ; en caso contrario devuelve cero
) ;_ fin de if
) ;_ fin de lambda 7.- y los valores devueltos quedan
; en una lista

) ;_ fin de function
(reverse numbin)
) ;_ fin de mapcar
) ;_ fin de apply
nil
) ;_ fin de if
) ;_ fin de defun
;;;
;;;Función filtro de entrada, considerando los posibles tipos de entrada:
;;;Lista, cadena o número
;;;los únicos términos aceptados serán en cualquier caso ceros o unos
;;;de detectarse otro valor, la función devuelve NIL
;;;Otro error derivaría de que la lista fuera un par punteado
;;;Para comprobarlo utilizaríamos la función STD-DOTTED-PAIR-P adaptada de
;;;la Standard LISP library de Reini Urban
;;;
(defun Decimal (numbin /)
(cond
((STD-DOTTED-PAIR-P numbin)
(terpri)
(princ numbin)
(princ " no es un valor admitido.")
(princ)
)
((listp numbin)
;;si es lista, convierte los términos
(setq
numbin ;;que sean cadenas en números
;;(o átomos simbólicos si fueran letras)

(mapcar
(function (lambda (term)
(if (stringp term)
(read term)
term
) ;_ fin de if
) ;_ fin de lambda
) ;_ fin de function
numbin
) ;_ fin de mapcar
) ;_ fin de setq
(ConvierteDecimal numbin)
)
((numberp numbin)
;;si es número lo convierte en cadena para después hacerlo lista
(setq numbin (Numero->Lista numbin))
(ConvierteDecimal numbin)
)
((stringp numbin)
(setq numbin (mapcar 'read (Cadena->Lista numbin)))
(ConvierteDecimal numbin)
)
(t
(terpri)
(princ numbin)
(princ " no es un valor admitido.")
(princ)
)
) ;_ fin de cond
) ;_ fin de defun

A continuación algunos ejemplos tomados de la consola de VISUAL Lisp:

A continuación analizaremos la función LOGIOR.