Tamas K Papp <tkpapp@gmail.com> wrote:
+
 I am generating LaTeX tables of numbers, and I am aligning the numbers
 on the decimal point (using the standard r@{}l trick). For that I
 need to separate them into 2 parts, one before and one after (and
 including) the decimal point, and I also constrain the number of
 digits in the latter.

 The best solution I could come up with was extracting from the output
 of format, like this:

 (defun float2part (x digits)
 (multiplevaluebind (int frac) (truncate x)
 (values (format nil "~d" int)
 (if (plusp digits)
 (subseq (format nil "~,vf" digits (abs frac)) 1)
 ""))))

 Examples:

 (float2part pi 2) ; "3", ".14"
 (float2part ( pi) 2) ; "3", ".14"
 (float2part 1239.93 3) ; "1239", ".930"
 (float2part 1239.93 3) ; "1239", ".930"
 (float2part pi 0) ; "3", ""

 This works fine, and it does not need to be fast. I am just asking if
 there is a more elegant way I missed.
+
Not more elegant, but perhaps a tiny bit simpler:
(defun float2part (x digits)
(let* ((string (format nil "~,vf" digits x))
(pos (position #\. string)))
(values (subseq string 0 pos)
(if (plusp digits) (subseq string pos) ""))))
I don't know exactly what you need for your table, but given that
you already know the number of fractions digits you want to display,
you could simply supply the filler in a single FORMAT and not have
to take stuff apart and put it back together again, e.g.:
> (defun floataligndot (x digits maxdigits width)
(let* ((rfill ( maxdigits digits))
(lfill ( width rfill)))
(format t "~v,vf~va~%" lfill digits x rfill " ")))
FLOATALIGNDOT
> (loop for v in (list pi ( pi) 1239.93 1239.93 pi)
and d in '(2 2 3 3 0) do
(floataligndot v d 5 12))
3.14
3.14
1239.930
1239.930
3.
NIL
>
[Yes, I see that this fails to suppress the "." on the last entry,
but I wasn't sure whether that was a hard requirement or not.]
Rob

Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)5722607