2.3.4.4.2. Binary->Decimal Conversion.

This function, complementary to the previous one, allows us to do the conversion in the opposite direction, starting from a binary value and converting it to decimal.
Although the data entry type is most likely to be numeric, we have designed an input filter function that will analyze, through a COND the possible entries, admitting lists and strings and rejecting any other data type.
In case the data is not one of these three supported types, an error message will be printed. If the data is admitted but is not of a binary character (includes terms other than zero or one), the function will return NIL.

;;;DECIMAL.LSP
;;;It receives a binary number and converts it to decimal.
;;;It should check the type of data received, which can be
;;;string, number or list.

;;;
;;;BIT auxiliary function.
;;;Returns the bit's decimal value at the specified position:
;;;
(defun Bit (pos) (lsh 1 (1- pos)))
;;;
;;;
;;;Function used to update the position index.
;;;
(defun PosBit ()
(if (null posicion)
(setq posicion 1)
(setq posicion (1+ posicion))
) ;_ end of if
) ;_ end of defun
;;;
;;;PREDICATES DEFINED FOR THIS FUNCTION:
;;;Three predicates are used expressly as input filters:
;;; STRINGP, STD-DOTTED-PAIR-P and BINARYP

;;;
;;;STRINGP predicate
;;; Checks if the data received is a string

;;;
(defun stringp (datum) (equal (type datum) 'STR))
;;;
;;;STD-DOTTED-PAIR-P Predicate
;;; Verifies that the argument received is a dotted pair.
;;; Adapted from Reini Urban's Standard Lisp Library.

;;;
(defun STD-DOTTED-PAIR-P (lst)
(and (vl-consp lst) (not (listp (cdr lst))))
) ;_ end of defun
;;;
;;;Binaryp Predicate
;;;Checks that the list only includes 0 or 1 values.

;;;
(defun Binaryp (numbin /)
(apply 'and
(mapcar '(lambda (term) (or (equal term 0) (equal term 1)))
numbin
) ;_ end of mapcar
) ;_ end of apply
) ;_ end of defun
;;;
;;;NUMBER->LIST Utility function
;;;Receives any decimal number and returns the isolated digits in list format.
;;;If the number is real it is truncated, neglecting the decimals.

;;;
(defun Number->List (number / lst)
(while (> number 0)
(setq lst (cons (rem (fix number) 10) lst))
(setq number (/ (fix number) 10))
) ;_ end of while
lst
) ;_ end of defun
;;;
;;;String->List Utility Function
;;; Receives a string of characters and returns the isolated characters
;;;in list format.

;;;
(defun String->List (string)
(mapcar
'chr ;3.- converts the ASCII
; codes into characters

(vl-string->list ;2.- converts the string into
; a list of ASCII codes

string
) ;_ end of vl-string->list
) ;_ end of mapcar
) ;_ end of defun
;;;
;;; Function ConvertDecimal.
;;; Performs the conversion. Since the evaluation is always from left to right,
;;; the list must be inverted to start checking by the last bit on the right.
;;; This checking is done by mapping a LAMBDA function to the list, which checks
;;; if the number is zero and in case it is not, inserts the decimal value of
;;; the bit in the list.
;;; Once this mapping is completed, the '+ function is applied to add all these
;;; values, with which we obtain the result of the
binary->decimal conversion.
;;; Returns a decimal number

;;;
(defun ConvertDecimal (numbin / position)
(if (Binaryp numbin)
(apply
'+ ; adds the values of the list
; returned by MAPCAR

(mapcar
(function
(lambda (x)
(PosBit) ;5.- checks the position variable
(if (not (zerop x))
(bit position)
0 ; in the opposite case returns zero
) ;_ end of if
) ;_ end of lambda 7.- and the values returned are stored
; in a list

) ;_ end of function
(reverse numbin)
) ;_ fin de mapcar
) ;_ fin de apply
nil
) ;_ fin de if
) ;_ fin de defun
;;;
;;; Input filter function, considering possible input types:
;;; List, string or number.
;;; The only accepted terms will in any case be zeros or ones.
;;; If another value is detected, the function returns NIL.
;;; Another error would be that the list was a dotted pair.
;;; To verify this, we use the STD-DOTTED-PAIR-P function, adapted from
;;; Reini Urban's Standard LISP library.

;;;
(defun Decimal (numbin /)
(cond
((STD-DOTTED-PAIR-P numbin)
(terpri)
(princ numbin)
(princ " is not an admitted value.")
(princ)
)
((listp numbin)
;;if list, converts its terms
(setq
numbin ;;if strings into numbers
;;(or symbolic atoms if characters)

(mapcar
(function (lambda (term)
(if (stringp term)
(read term)
term
) ;_ end of if
) ;_ end of lambda
) ;_ end of function
numbin
) ;_ end of mapcar
) ;_ end of setq
(ConvertDecimal numbin)
)
((numberp numbin)
;;if number, it is converted into string and later into list
(setq numbin (Number->List numbin))
(ConvertDecimal numbin)
)
((stringp numbin)
(setq numbin (mapcar 'read (String->List numbin)))
(ConvertDecimal numbin)
)
(t
(terpri)
(princ numbin)
(princ " is not an admitted value.")
(princ)
)
) ;_ end of cond
) ;_ end of defun

Here are some examples copied from the VISUAL Lisp console: