Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

how to suppress tailing zeros with FORMAT ~F

1 view
Skip to first unread message

jimka

unread,
Jan 20, 2009, 11:23:31 AM1/20/09
to
(format nil "~4,3F" some-number)
will print eactly 3 digits after the decimal, if some-number is 3.2,
then it prints 3.200. How can i tell format to
supress the trailing 0's? anybody know?
obviously i could as format to print to a string, then post-process
the string... but maybe there's an easier way.

-jim

Alexander Lehmann

unread,
Jan 20, 2009, 12:28:45 PM1/20/09
to

This is neither pretty nor concise, but if it helps:

(defun trailing-zeros-removed (val &optional (prec 3))
(format t
(concatenate 'string
"~,"
(do ((p prec (1- p))
(v (* val (expt 10 prec)) (/ v 10)))
((or (<= p 1) (boole boole-and (truncate v) 1))
(write-to-string p)))
"f")
val))

w_a_...@yahoo.com

unread,
Jan 20, 2009, 4:19:41 PM1/20/09
to

Ruby:

format( "%.3f", 8.2 ).sub( /0?0$/, "" )
==>"8.2"
format( "%.3f", 8.0 ).sub( /0?0$/, "" )
==>"8.0"
format( "%.3f", 8.55 ).sub( /0?0$/, "" )
==>"8.55"

Marek Kubica

unread,
Jan 20, 2009, 5:52:12 PM1/20/09
to
On Tue, 20 Jan 2009 13:19:41 -0800 (PST)
w_a_...@yahoo.com wrote:

> Ruby:
>
> format( "%.3f", 8.2 ).sub( /0?0$/, "" )
> ==>"8.2"
> format( "%.3f", 8.0 ).sub( /0?0$/, "" )
> ==>"8.0"
> format( "%.3f", 8.55 ).sub( /0?0$/, "" )
> ==>"8.55"

Though I doubt that the original poster asked for a Ruby solution in
comp.lang.lisp. Using regular expressions is possible in Lisp, too.

regards,
Marek

K Livingston

unread,
Jan 20, 2009, 6:36:47 PM1/20/09
to


Format ~4,3F is a little weird, by the way,.. you are not going to get
a leading zero either for 0.211 unless you give it ~5,3 since the
decimal point is counted against the first parameter.

Assuming the leading zero is ok... simply just ~4F (or ~5F) seems to
do (mostly) what you want except when it's just 3.2 or something like
3.201 you will get " 3.2", (note the leading space) since you forced
it to be 4 characters wide. if you can tolerate that? that's
probably your best bet.

As an alternative to Alexander's function of consing up the format
string you could put your number through a function that just lops off
precision below the level you wanted before passing it to simply
format ~F.

Kevin

Madhu

unread,
Jan 20, 2009, 9:49:00 PM1/20/09
to
* jimka <13138143-99fd-4241...@d36g2000prf.googlegroups.com> :
Wrote on Tue, 20 Jan 2009 08:23:31 -0800 (PST):

Or you could pre-process the number and use PRIN1.

(defun round-to-accuracy (value digits-after-decimal-point)
"Internal. Round VALUE to DIGITS decimal places."
(declare (type (integer 0 10) digits-after-decimal-point))
(let ((precision (expt 10 digits-after-decimal-point)))
(if (integerp value)
value
(coerce
(/ (round (* precision value)) precision)
(type-of value)))))

I use this in some cases where I require the output of my program to be
identical to the output of [non lisp] program.

note in the case of FORMAT's float directives it makes sense to not do
this because when you are dealing with CL floats, depending on how your
3.2 was represented, rounding and printing them could possibly end up
with 3.199 (say) [ANS section 22.3.3.1]

--
Madhu

jimka

unread,
Jan 21, 2009, 4:50:51 AM1/21/09
to
hi wax, if you read my original post you'll see i wanted to do it
without
post processing the string. If i simply want to kill trailing zeros
there are 1e3s of ways of doing it with and without resorting to
regular expressions.

0 new messages