Decimal-to-Binary Converter

Discussion of Common Lisp
Post Reply
esx_raptor
Posts: 2
Joined: Sun Apr 11, 2010 12:12 am

Decimal-to-Binary Converter

Post by esx_raptor » Sun Apr 11, 2010 12:17 am

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
Last edited by esx_raptor on Sun Apr 11, 2010 8:20 am, edited 1 time in total.

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Binary-to-Decimal Function

Post by ramarren » Sun Apr 11, 2010 1:33 am

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).

esx_raptor
Posts: 2
Joined: Sun Apr 11, 2010 12:12 am

Re: Binary-to-Decimal Function

Post by esx_raptor » Sun Apr 11, 2010 8:39 am

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);
   }
}

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Decimal-to-Binary Converter

Post by ramarren » Sun Apr 11, 2010 10:01 am

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.

Jasper
Posts: 209
Joined: Fri Oct 10, 2008 8:22 am
Location: Eindhoven, The Netherlands
Contact:

Re: Decimal-to-Binary Converter

Post by Jasper » Sun Apr 11, 2010 12:37 pm

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)))

Post Reply