[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


I found a couple of bugs in the function float-to-string that I sent out
earlier. Specifically, it did not work well for negative numbers or numbers
which were slightly less than integers. Here's a revised version:

;;; this function needs a better name
(defun round-significand (number fractional-digits)
  "Round the significand for display."
  (if fractional-digits
    (let ((divisor (expt 10 (- fractional-digits))))
      (* (round number divisor) divisor))
    (values number)

;;; this is a fast alternative to format for floating-point numbers
;;; with no exponent
(defun float-to-string (number fractional-digits)
  "Converts a floating-point number to a string, ~
   with a given number of digits following the decimal point."
  (multiple-value-bind (integral fractional)
                       (truncate (round-significand number fractional-digits))
    (let ((int-string (integer-to-string integral)))
      ;; dont mess around with fractions if you dont have to
      (if (zerop fractional-digits)
        (concatenate 'string int-string ".")
        (let* ((fract-int (* (expt 10 fractional-digits)
                             ;; use abs because truncate signs the remainder
                             (abs fractional)))
               (fract-string (integer-to-string fract-int))
               ;; pad fraction with enough zeros to separate it from decimal
               (pad-string (make-string (- fractional-digits (length fract-string))
                                        :initial-element #\0)))
          (concatenate 'string int-string "." pad-string fract-string)