Page 1 of 1

Decimal-to-Binary Converter

Posted: Sun Apr 11, 2010 12:17 am
by esx_raptor
Hey guys!

I'm kind of new to LISP and because of this, I have run into the following problem while trying to implement a decimal-to-binary converter:

Code: Select all

(defun bin (x)
   (if (eql x 0)
      0
      (progn
         (bin (round (/ x 2)))
         (mod x 2))))
The problem here is that I don't know how to do some sort of "integer concatenation", thus I only get a single value, like so:

Code: Select all

> (bin 5)
1
Help? :D

Re: Binary-to-Decimal Function

Posted: Sun Apr 11, 2010 1:33 am
by ramarren
esx_raptor wrote:I have run into the following problem while trying to implement a binary-to-decimal converter:
Your problem is that you don't know what "integer", "binary" and "decimal" actually mean. Please first learn the difference between an object (in this case, integers) and its representation (in this case, numeral system).

Re: Binary-to-Decimal Function

Posted: Sun Apr 11, 2010 8:39 am
by esx_raptor
Ramarren wrote:
esx_raptor wrote:I have run into the following problem while trying to implement a binary-to-decimal converter:
Your problem is that you don't know what "integer", "binary" and "decimal" actually mean. Please first learn the difference between an object (in this case, integers) and its representation (in this case, numeral system).
Excuse me? I'm a C programmer, man, and I'm pretty sure I know what those are.

Trying to solve a problem at 3:00 AM in the morning doesn't help with correct word structuring/question asking either.

I guess I should have simply asked the question: "How To Display Something in LISP to Standard Output? (Terminal?)"

Anyways, here's the C equivalent of what I'm trying to do on LISP:

Code: Select all

void dtb(int x) {
   if (x == 0)
      printf(0);
   else {
      dtb(x/2);
      printf("%d", x % 2);
   }
}

Re: Decimal-to-Binary Converter

Posted: Sun Apr 11, 2010 10:01 am
by ramarren
esx_raptor wrote:Excuse me? I'm a C programmer, man, and I'm pretty sure I know what those are.
Well, that certainly wasn't clear from the original post, and the term "integer concatenation" somewhat indicated that you do not, even in scare quotes.

My point is, "binary" and "decimal" are properties of representation. Therefore conversion from decimal to binary cannot operate on integers, since integers are not "decimal". In Lisp the number read base is even configurable. Therefore, an argument to such a converter would have to be a sequence of digits, and the output likewise. Incidentally, there was no indication that you wanted to output such a sequence to standard output, either.

An example implementation of what I meant:

Code: Select all

(defun dtb (decimal)
  (let ((decimal-vector (coerce decimal '(vector (integer 0 9)))))
    (if (zerop (length decimal-vector))
        (list 0)
        (let ((anumber (loop for d from (1- (length decimal-vector)) downto 0
                             for f = 1 then (* 10 f)
                             summing (* (aref decimal-vector d) f))))
          (reverse (loop for number = anumber then (floor number 2)
                         while (plusp number)
                         collect (mod number 2)))))))
esx_raptor wrote:"How To Display Something in LISP to Standard Output? (Terminal?)"
There are rather many ways, and that is even without getting into formatted output.

Re: Decimal-to-Binary Converter

Posted: Sun Apr 11, 2010 12:37 pm
by Jasper
Forgive the mis-estimation.. I thought the same reading the first post here. Anyway, more similar to the C code you gave:

Code: Select all

(defun dtb (x &optional (callback #'princ))
  (unless (= x 0)
    (dtb (floor x 2) callback) ;This Floor also divides by two. (default is 1)
    (funcall callback (mod x 2))));Could also add (values) at the end to indicate that it is not supposed to return anything.
You can make it collect with something like nconcing:

Code: Select all

(defun dtb-collect (x)
  (nconcing ()
    (dtb x #'nconc-it)
    nconc-result))
Where #'conc-it==(function conc-it) (#'.. is just dispatch to write (function ..), and this function and variable is created locally in the nconcing macro. Tbh, without handy macros for it collecting, in the same order as you collect it can be rather a pain in the ass in CL, luckily you can use stuff like Mapcar, Mapcan etcetera, aswel as macros like Nconcing. Personally i call my versions Collecting and the single-collect version within it Collect (but older version still is accident-waiting-to-happen version)

You could also do it with DO:

Code: Select all

(defun dtb-collect (x)
  (declare (type fixnum x)) ;This 'integer' most-positive-fixnum== ~1e18
  (do ((x x (floor x 2))
       (list nil (cons (mod x 2) list)))
      ((= x 0) list)))