2.3.4.4.1. Conversión Decimal->Binario

Aplicando lo visto hasta ahora podemos crear una función que convierta cualquier número decimal, positivo o negativo, en su representación binaria.
El manual de Personalización de AutoCAD  propone una solución, pero que es aplicable sólo a enteros positivos:

;;;Del manual de Personalización:
;;;convierte un entero POSITIVO a una cadena
;;;en la base dada:
(defun base (bas int / ret yyy zot)
(defun zot (i1 i2 / xxx)
(if (> (setq xxx (rem i2 i1)) 9)
(chr (+ 55 xxx))
(itoa xxx)
) ;_ fin de if
) ;_ fin de defun
(setq ret (zot bas int)
yyy (/ int bas)
) ;_ fin de setq
(while (>= yyy bas)
(setq ret (strcat (zot bas yyy) ret))
(setq yyy (/ yyy bas))
) ;_ fin de while
(strcat (zot bas yyy) ret)
) ;_ fin de defun

Para números enteros positivos opera correctamente pero no así para los negativos, como puede verse en los siguientes ejemplos:

Nuestra función BINARIO tiene en cuenta la longitud de palabra del sistema operativo y devuelve la secuencia correcta de ceros y unos incluso cuando se trate de valores negativos. La función espera recibir un entero, pero prevé el caso de un número real, truncándolo al entero menor más cercano.
Se definen las funciones utilitarias BIT y POSBIT, esta última utilizada para guardar el valor de la posición del bit que se analiza. La conversión en sí misma la realiza la función ConvierteBinario que recibe como argumentos el número a convertir y una función predicado a plicar según el número sea positivo o negativo.
Esta función de conversión es llamada desde la función principal BINARIO que analiza si el número recibido es positivo o negativo. En caso de ser negativo pasa a la función de conversión su NOT lógico (~ numdec) y el predicado '= en lugar del número recibido y el predicado '/= que pasaría en caso de ser el número positivo.

;;;Binario.lsp
;;;El ciclo continuará hasta que LSH devuelva un valor negativo
;;;significando que se ha llegado al final de la palabra (posición
;;;extrema izquierda). El valor binario es devuelto en formato de lista.
;;;
;;; Función auxiliar Bit: devuelve el valor decimal del bit en la
;;; posición indicada.

;;;
(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
;;;
;;;
;;;Función para procesamiento del número decimal
;;;Recibe como argumento el predicado a aplicar
;;;según sea el argumento numérico positivo o negativo
;;;
(defun ConvierteBinario (numdec predicado / posicion numbin)
(while (not (minusp (bit (1- (PosBit)))))
(setq numbin
(cons
(if
(apply
predicado
(list (logand (bit posicion) (fix numdec)) 0)
) ;_ fin de apply
1
0
) ;_ fin de if
numbin
) ;_ fin de cons
) ;_ fin de setq
) ;_ fin de while
) ;_ fin de defun
;;;
;;;Función principal
;;;Tiene en cuenta si se trata de un número positivo o negativo:
;;;
(defun Binario (numdec /)
(if (minusp numdec)
(ConvierteBinario (~ numdec) '=)
(ConvierteBinario numdec '/=)
) ;_ fin de if
) ;_ fin de defun

A diferencia de la función BASE, se obtiene una respuesta correcta tanto de enteros positivos como negativos:

Si deseáramos el resultado en formato cadena en lugar de lista, bastaría mapear 'ITOA a la lista devuelta para convertir los enteros en cadena y aplicarle después 'STRCAT para unir los caracteres en una cadena única:

Dedicaremos la próxima sección a la conversión en el otro sentido, de binario a decimal.


** AutoCAD Versión 13. Manual de Personalización. Autodesk, Inc. 1994. ISBN: 2-88447-327-0. pág. 249