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

Help with using format control strings

10 views
Skip to first unread message

Jon Allen Boone

unread,
Oct 15, 2002, 4:16:11 PM10/15/02
to
Folks,

I'm curious about the On-Line HyperSpec section which describes
the ~R format control string. The URL is:

http://www.lispworks.com/reference/HyperSpec/Body/22_cba.htm

It describes the full form of the control string as:

~radix,mincol,padchar,commachar,comma-intervalR

although the ~B format control string is:

~mincol,padchar,commachar,comma-intervalB

The examples given [at the URL I included] include:

(format nil "~19,0,' ,4:B" 3333) => "0000 1101 0000 0101"

Every CL implementation I've tried fails on this example
[apparently because the 0 needs to be single-quoted to make it a
character?]. I tried CLISP, CMUCL, LispWorks(win32), ACL(both win32
and Linux) and CormanLisp.

I take it that the format control should do the following:

19 minimum columns
0 is the pad char
<SPACE> is the commachar
comma-chars should occur every 4 bits

Now, if I replace 0 with '0 it produces the following output on
all of the above mentioned implementations:

(format nil "~19,'0,' ,4:B" 3333)
"000001101 0000 0101"

Is the pad-char output [the first 4 leading '0s] not supposed to
be comma'd every 4 characters as the rest of the output is [and as
the example indicates]?

This came up in some exercises I'm working through in a new book,
_Hacker's Delight_ by Henry S. Warren, Jr. [ISBN 0-201-91465-4]
which is in spirit a follow-on to the 1972 MIT Research memo HAKMEM
[according to Guy L. Steele, Jr., who wrote the Foreword].

Rather than just memorize the formulas, I am attempting to
convince myself that they are correct by looking at the binary
representation of numbers and performing the operations in my head.
So, I wanted to use 32-bit padded binary representation to print out
the numbers.

On a related note, I'm confused about how to go about getting a
binary representation of a negative number. When I hand a negative
value to the format control above, it just sticks a negative sign in
front of the binary digits that represent the absolute value of the
number in question - like this:

(format nil "~19,'0,' ,4:B" -3333)
"0000-1101 0000 0101"

Can someone steer me in the right direction?

-jon
--
------------------
Jon Allen Boone
ipmo...@delamancha.org

Erik Naggum

unread,
Oct 15, 2002, 10:34:11 PM10/15/02
to
* Jon Allen Boone

| Every CL implementation I've tried fails on this example [apparently
| because the 0 needs to be single-quoted to make it a character?].

That example is one of the very small number of actual bugs in the
standard. Note, however, that examples are not authoritative in any way
and are not formally part of the standard. This is an editorial decision
I support wholeheartedly. Examples are generally a bad thing outside of
carefully controlled educational settings (as tutorials) because people
just as easily learn wrong things from them as the intended purpose if
they are not sufficiently guided in what they are supposed to learn.

In this case, you have not read the specification, but have "believed"
the example. There is really nothing more important to say on this than
that this is the wrong order of preference. The right order of preference
in a specification and especially a standard is the normative clauses,
then the normative clauses, then the normative clauses again just to make
sure, and only if you got the point from the normative clauses, you can
look at the non-normative clauses, in which you should report anything
not immediately reconcilable with the normative clauses as a mistake in
the standard, not with your understanding of it.

| This came up in some exercises I'm working through in a new book,
| _Hacker's Delight_ by Henry S. Warren, Jr. [ISBN 0-201-91465-4] which is
| in spirit a follow-on to the 1972 MIT Research memo HAKMEM [according to
| Guy L. Steele, Jr., who wrote the Foreword].

Thanks for the reference. I had somehow missed this book.

| Rather than just memorize the formulas, I am attempting to convince
| myself that they are correct by looking at the binary representation of
| numbers and performing the operations in my head. So, I wanted to use
| 32-bit padded binary representation to print out the numbers.

Since you are on the topic of cute hacks, try

(format <stream> "~41,'0,' ,4:B" (dpb <integer> (byte 32 0) (ash 1 32)))

This also solves your negative 32-bit integer printing problem neatly.
Exercise: Explain why. :)

--
Erik Naggum, Oslo, Norway

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.

Thomas A. Russ

unread,
Oct 17, 2002, 7:39:13 PM10/17/02
to
Jon Allen Boone <ipmo...@delamancha.org> writes:

> Now, if I replace 0 with '0 it produces the following output on
> all of the above mentioned implementations:
>
> (format nil "~19,'0,' ,4:B" 3333)
> "000001101 0000 0101"
>
> Is the pad-char output [the first 4 leading '0s] not supposed to
> be comma'd every 4 characters as the rest of the output is [and as
> the example indicates]?

Apparently the implementations all add the pad character to the output
to fill it in without applying the comma rule.

I think a while back (a fairly long while), this was discussed here. I
think the final sense was that this was a fairly reasonable practice,
since otherwise Lisp would need to do rather involved inference to
figure out what was reasonable. This is mainly because you would really
only want to have the padchar following the comma convention if it were
a legal digit character. If one were to choose * instead of 0

(format nil "~19,'*,' ,4:B" 3333)

"*****1101 0000 0101" is probably nicer than
"**** 1101 0000 0101"

This is even more clearly so with the following example:

(format nil "~19,'*,' ,4:B" 3333)
"******101 0011 0101" versus
"**** *101 0011 0101"

It really only makes sense to use the comma character when one is trying
to zero pad a number. Now I suppose that one could make a case for
treating zero specially, but that wasn't done.

And the : and @ flags were already taken :<


> On a related note, I'm confused about how to go about getting a
> binary representation of a negative number. When I hand a negative
> value to the format control above, it just sticks a negative sign in
> front of the binary digits that represent the absolute value of the
> number in question - like this:
>
> (format nil "~19,'0,' ,4:B" -3333)
> "0000-1101 0000 0101"
>
> Can someone steer me in the right direction?

Well, that is because there isn't really a 2's complement way of storing
arbitrary precision integers.

I think that you really need to come up with your own specialized
formatting routines for handling this.

--
Thomas A. Russ, USC/Information Sciences Institute t...@isi.edu

0 new messages