Convert fractions from decimal to binary

2019-10-04 15:40发布

问题:

I want to convert the number 8.7 to binary.

I know the commands

(format nil "~b" (rationalize 8.7)) ===>
1010111/1010

or

(format nil "~b" (/ 87 10))====> 1010111/1010

We observe if we do the quotient binary 1010111/1010 we obtain 1000.1011001100110011001100110011.

Is possible to obtain in Lisp

(8.7)_2 ~ 1000.1011001100110011001100110011?

If yes, how?

回答1:

"2.718..." is equal to 2 * 10^1 + 7 * 10^-1 + 1 * 10^-2 + 8 * 10^-3... This means that you can generate the string by the reverse process of concatenating string(n / base^i) where i is the index into the string and n is the value that still needs to be converted to base. It's essentially a greedy change-making algorithm.

The following roughly works, with no guarantee that it produces the exact IEEE 754 fraction. It should be as accurate as your implementation's floats

(defun fractional-binary (fractional &optional (place 1) (result "."))
  (if (zerop fractional)
      result
      (let ((fraction (expt 2 (- place))))
        (if (<= fraction fractional)
            (fractional-binary (- fractional fraction)
                               (1+ place)
                               (concatenate 'string result "1"))
            (fractional-binary fractional
                               (1+ place)
                               (concatenate 'string result "0"))))))

CL-USER> (fractional-binary .7)
".101100110011001100110011"


标签: binary lisp