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

demonic numbers !

32 views
Skip to first unread message

Christophe Turle

unread,
Feb 3, 2005, 3:18:34 PM2/3/05
to

How to make CL (Clisp) read decimal numbers as rational ?

For example, i have to read one entry : 102.0051 but this is interpreted as
a float ! And i don't know how to write the function F such that :

(F entry) => "102005100" which in theory is just 'multiply by 1000000'.

If the entry was a double-float it works with rationalize, but i can't
change the inputs (and i don't want too, i don't want to know what the
underlying number representation is !)


;; this sums up the problem ;)
> (* 102.0051 10000)
1020050.94

I have an idea which works but i don't know how to hook it :
102.0051 => "102.0051" => "102" "0051" => (+ 102 (/ 51 (expt 10 4))) =>
1020051/10000

The problem here is that i do the job of the reader a second time and after
a potential loss of precision :

CL-USER> (read-from-string ".111111111101")
0.11111111

So, is there a way to hook this directly into the reader ??
and switching by using (setf *read-decimal-as* :rational) and (setf
*read-decimal-as* :float)

--
___________________________________________________________
Christophe Turle.
sava preview http://perso.wanadoo.fr/turle/lisp/sava.html
(format nil "~a@~a.~a" 'c.turle 'wanadoo 'fr)


Pascal Bourguignon

unread,
Feb 3, 2005, 3:56:39 PM2/3/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> How to make CL (Clisp) read decimal numbers as rational ?
>
> For example, i have to read one entry : 102.0051 but this is interpreted as
> a float ! And i don't know how to write the function F such that :
>
> (F entry) => "102005100" which in theory is just 'multiply by 1000000'.
>
> If the entry was a double-float it works with rationalize, but i can't
> change the inputs (and i don't want too, i don't want to know what the
> underlying number representation is !)

Merely, by introducing a reader macro that will do the rational reading.
For example, you could use:

#/123.4567 --> 1234567/1000

You might get inspiration from the currency syntax macro in my
COM.INFORMATIMAGO.COMMON-LISP.INVOICE package.

See: http://www.informatimago.com/develop/lisp/#cvs
for CVS checkout instructions.


--
__Pascal Bourguignon__ http://www.informatimago.com/

Barry Margolin

unread,
Feb 4, 2005, 1:08:43 AM2/4/05
to
In article <42028742$0$513$626a...@news.free.fr>,
"Christophe Turle" <ctu...@nospam.com> wrote:

> How to make CL (Clisp) read decimal numbers as rational ?
>
> For example, i have to read one entry : 102.0051 but this is interpreted as
> a float ! And i don't know how to write the function F such that :
>
> (F entry) => "102005100" which in theory is just 'multiply by 1000000'.
>
> If the entry was a double-float it works with rationalize, but i can't
> change the inputs (and i don't want too, i don't want to know what the
> underlying number representation is !)

RATIONALIZE should work with any type of float, not just double-float.

--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***

Pascal Bourguignon

unread,
Feb 4, 2005, 5:31:26 AM2/4/05
to
Barry Margolin <bar...@alum.mit.edu> writes:

> In article <42028742$0$513$626a...@news.free.fr>,
> "Christophe Turle" <ctu...@nospam.com> wrote:
>
> > How to make CL (Clisp) read decimal numbers as rational ?
> >
> > For example, i have to read one entry : 102.0051 but this is interpreted as
> > a float ! And i don't know how to write the function F such that :
> >
> > (F entry) => "102005100" which in theory is just 'multiply by 1000000'.
> >
> > If the entry was a double-float it works with rationalize, but i can't
> > change the inputs (and i don't want too, i don't want to know what the
> > underlying number representation is !)
>
> RATIONALIZE should work with any type of float, not just double-float.

That's not exactly the behavior we want here.


--
__Pascal Bourguignon__ http://www.informatimago.com/

-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCS d? s++:++ a+ C+++ UL++++ P--- L+++ E+++ W++ N+++ o-- K- w---
O- M++ V PS PE++ Y++ PGP t+ 5+ X++ R !tv b+++ DI++++ D++
G e+++ h+ r-- z?
------END GEEK CODE BLOCK------

mmcconn...@yahoo.com

unread,
Feb 4, 2005, 12:01:24 PM2/4/05
to
In your application, do you know for sure that the decimals are exact?
That is, if your file has 1.3333, are you sure it's 13333/10000 and not
4/3 ?

If so, follow Pascal's suggestion, or use something like
(defun meg (x)
(round (* 1000000 x)))

Christophe Turle

unread,
Feb 5, 2005, 1:33:35 PM2/5/05
to
"Pascal Bourguignon" <sp...@mouse-potato.com> a écrit dans le message de
news: 87zmylc...@thalassa.informatimago.com...

> "Christophe Turle" <ctu...@nospam.com> writes:
>
>> How to make CL (Clisp) read decimal numbers as rational ?
>>
>> For example, i have to read one entry : 102.0051 but this is interpreted
>> as
>> a float ! And i don't know how to write the function F such that :
>>
>> (F entry) => "102005100" which in theory is just 'multiply by 1000000'.
>>
>> If the entry was a double-float it works with rationalize, but i can't
>> change the inputs (and i don't want too, i don't want to know what the
>> underlying number representation is !)
>
> Merely, by introducing a reader macro that will do the rational reading.
> For example, you could use:
>
> #/123.4567 --> 1234567/1000

I can't change inputs. I have the string "(x 123.2569 y 1256.3588)" input
for example. So i can't introduce reader macros :(

Actually, i'm binding *read-default-float-format*

(let ((*read-default-float-format* 'double-float))
(read-from-string "(x 123.2569 y 1256.3588)" ))


But the problem comes again if double (or longer) float is not sufficient...

Christophe Turle

unread,
Feb 5, 2005, 1:36:12 PM2/5/05
to
"Barry Margolin" <bar...@alum.mit.edu> a écrit dans le message de news:
barmar-4D7E8B....@comcast.dca.giganews.com...

> In article <42028742$0$513$626a...@news.free.fr>,
> "Christophe Turle" <ctu...@nospam.com> wrote:
>
>> How to make CL (Clisp) read decimal numbers as rational ?
>>
>> For example, i have to read one entry : 102.0051 but this is interpreted
>> as
>> a float ! And i don't know how to write the function F such that :
>>
>> (F entry) => "102005100" which in theory is just 'multiply by 1000000'.
>>
>> If the entry was a double-float it works with rationalize, but i can't
>> change the inputs (and i don't want too, i don't want to know what the
>> underlying number representation is !)
>
> RATIONALIZE should work with any type of float, not just double-float.


i'm afraid not (CLisp 2.33)

CL-USER> (rationalize 102.0051)
60081/589

CL-USER> (rationalize 102.0051d0)
1020051/10000

Christophe Turle

unread,
Feb 5, 2005, 1:41:20 PM2/5/05
to
<mmcconn...@yahoo.com> a écrit dans le message de news:
1107536484.7...@g14g2000cwa.googlegroups.com...

> In your application, do you know for sure that the decimals are exact?
> That is, if your file has 1.3333, are you sure it's 13333/10000 and not
> 4/3 ?

yes i am.


> If so, follow Pascal's suggestion, or use something like
> (defun meg (x)
> (round (* 1000000 x)))


CL-USER> (defun meg (x)
(round (* 1000000 x)))

MEG

CL-USER> (meg 102.0051)
102005096
0.0

CL-USER> (meg 102.0051d0)
102005100
0.0d0


No, what i really want is a ->rational at the read time and without reader
macros since i don't control inputs :(

Pascal Bourguignon

unread,
Feb 5, 2005, 2:38:36 PM2/5/05
to
"Christophe Turle" <ctu...@nospam.com> writes:
> > Merely, by introducing a reader macro that will do the rational reading.
> > For example, you could use:
> >
> > #/123.4567 --> 1234567/1000
>
> I can't change inputs. I have the string "(x 123.2569 y 1256.3588)" input
> for example. So i can't introduce reader macros :(

The lisp reader is good to read lisp data. If you want to read
application specific data, then you have to implement your own reader.
Don't be misled by the parentheses. Check the Dragon Book.

--
__Pascal Bourguignon__ http://www.informatimago.com/

This is a signature virus. Add me to your signature and help me to live

Christophe Turle

unread,
Feb 5, 2005, 3:20:20 PM2/5/05
to
"Pascal Bourguignon" <sp...@mouse-potato.com> a écrit dans le message de
news: 87r7jub...@thalassa.informatimago.com...

> "Christophe Turle" <ctu...@nospam.com> writes:
>> > Merely, by introducing a reader macro that will do the rational
>> > reading.
>> > For example, you could use:
>> >
>> > #/123.4567 --> 1234567/1000
>>
>> I can't change inputs. I have the string "(x 123.2569 y 1256.3588)" input
>> for example. So i can't introduce reader macros :(
>
> The lisp reader is good to read lisp data. If you want to read
> application specific data, then you have to implement your own reader.

I see your point. Except that there's no way to write a number with a
decimal point in Lisp :(

0.111111 is not interpreted by Lisp (and other programming languages as
well)readers as it is for human readers :(

Is there a Lisp implementation which allows reading 0.11111 as it should ?

imho, 0.11111f should be interpreted as a float not 0.11111.

But i don't want to re-open a recent flame thread about this point, even if
... ;)

William Bland

unread,
Feb 5, 2005, 3:27:00 PM2/5/05
to
On Sat, 05 Feb 2005 20:38:36 +0100, Pascal Bourguignon wrote:

> "Christophe Turle" <ctu...@nospam.com> writes:
>> > Merely, by introducing a reader macro that will do the rational reading.
>> > For example, you could use:
>> >
>> > #/123.4567 --> 1234567/1000
>>
>> I can't change inputs. I have the string "(x 123.2569 y 1256.3588)" input
>> for example. So i can't introduce reader macros :(
>
> The lisp reader is good to read lisp data. If you want to read
> application specific data, then you have to implement your own reader.
> Don't be misled by the parentheses. Check the Dragon Book.


It's a bit messy, but the following seems to work ok for me:

(defvar *digits* '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\.))

(defun read-rational (stream char)
"read all decimals as rationals"
(let ((this-char nil)
(result (position char *digits*))
(n 0)
(position-of-dot nil))
(loop while (member (peek-char nil stream) *digits*) do
(setf this-char (read-char stream))
(if (eql this-char #\.)
(setf position-of-dot n)
(setf result (+ (* 10 result) (position this-char *digits*))))
(incf n))
(if position-of-dot
(/ result (expt 10 (1- (- n position-of-dot))))
result)))

(mapcar (lambda (c)
(set-macro-character c #'read-rational))
(remove #\. *digits*)) ;; \#. is used for other things!


Best wishes,
Bill.

Rahul Jain

unread,
Feb 6, 2005, 1:58:43 AM2/6/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> Is there a Lisp implementation which allows reading 0.11111 as it should ?

All do. Look at the paper on the META parser and just don't convert to
float in the stage where you compute the value. You'll end up with
11111/100000 as you "should".

--
Rahul Jain
rj...@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist

Rahul Jain

unread,
Feb 6, 2005, 2:00:22 AM2/6/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> "Barry Margolin" <bar...@alum.mit.edu> a écrit dans le message de news:
> barmar-4D7E8B....@comcast.dca.giganews.com...

>> RATIONALIZE should work with any type of float, not just double-float.
>
>
> i'm afraid not (CLisp 2.33)
>
> CL-USER> (rationalize 102.0051)
> 60081/589
>
> CL-USER> (rationalize 102.0051d0)
> 1020051/10000

I'm afraid so... Please explain how the above is incorrect.

Rahul Jain

unread,
Feb 6, 2005, 2:03:02 AM2/6/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> No, what i really want is a ->rational at the read time and without reader
> macros since i don't control inputs :(

You _must_ _not_ _use_ _the_ _lisp_ _reader_, _then_, _because_ _you_
_are_ _not_ _reading_ _lisp_.

To make it clear: The lisp reader reads lisp code. What you want to read
is not lisp code. Therefore, you do not want to use the lisp reader.

Kent M Pitman

unread,
Feb 6, 2005, 2:42:37 AM2/6/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> I can't change inputs. I have the string "(x 123.2569 y 1256.3588)" input
> for example. So i can't introduce reader macros :(

No, that's not so. That is, the assertion in your first sentence is not,
as you seem to suggest, the result of some logical implication from the
premise in the second sentence to an unavoidable conclusion in the third
sentence.

For example, you could make #\0, #\1, #\2, etc. be readmacros that
could then read the rest of the number in whatever format they liked.

(Don't do it globally, of course, make your own readtable. It won't be
program-friendly to do this, and Rahul Jain's observation is right
when he says "You must not use the lisp reader, then, because you are not
reading Lisp", to the extent that you are not using readmacros. You
can use readmacros, of course, in any Lisp code that is cooperating with
the syntax that the readmacros implement.)

I recall once making a readtable for FORTRAN in which every character in
the character set was a readmacro that just triggered the FORTRAN parser.
That's just an extreme trick, of course, but the point is that you have
a lot more flexibility than you think.

> Actually, i'm binding *read-default-float-format*
>
> (let ((*read-default-float-format* 'double-float))
> (read-from-string "(x 123.2569 y 1256.3588)" ))

Not that this matters, since you're wanting rationals. You're now dealing
in approximations. Though you may be able to help yourself a little by
looking at the function RATIONALIZE.

But look here, the real issue is something you're evading or that you
addressed before I started reading this thread:

I'll begin with a bold claim: A priori, no notation means anything.

Things ONLY mean something in the context of a person (or program)
creating text in a notation and a person (or program) interpreting that
text according to a mutually agreed set of rules.

This may seem obvious but I've got to wonder: Who is making up this text
that you cannot change?

People don't normally parenthesize things like that. They usually use
commas between items in lists, and usually do not put parens around lists
for that matter. So it sounds like someone with just a little too much
bad or partial knowledge of Lisp (possibly to include a well-meaning but
confused instructor or textbook), and that your initial constraint is the
real bug. It sounds like a fake constraint, and/or a job for a sed script.
Real programming does not have constraints like "you may not modify the
input data". Input data is there FOR THE PURPOSE OF being modified, and
in real programs, it is often cascaded through multiple filters before
getting to a form that it can be processed.

I once worked on a project for some people doing Gamma ray spectra analysis,
before the days of scanners and OCR technology, and someone wanted to turn
a science book full of data into something we could use in our programs.
Knowing there was Lisp involved, they told some secretary to "type in the
book" and "to use lots of parens because Lisp likes that". So tables got
typed in with parens here and there, but this was NOT lisp, and not really
even helpful. There were no conventions for what to do about missing columns,
funny chars like plus-or-minus, etc. The typist just "got creative" and
often not consistently. You problem sounds like a similar problem to what
I had, only "in the small". But I can tell you the ONLY thing that allowed me
to get the book parsed was that I was allowed to use all kinds of strategies
for transformation. Any kind of statement like "and you can't use readmacros"
would have been unreasonably restrictive and killed the project. You might as
well say "can't use right parens" or "can't use xor" or "can't use a jump
instruction". To what end?

There is a right time and a wrong time to solve a problem as explained.

It sounds to me like your BEST options are:

(a) to question whether the upstream program shouldn't produce
123/1000 instead of .123 if that's what it means

(b) to preprocess the string to change the format from .123 to 123/1000
before applying the lisp reader

and you should be considering solutions like readmacros and/or use of
double-floats + rationalize only if someone has tied your hands and made
it clear that they intend to make your life thus miserable.

Christophe Turle

unread,
Feb 6, 2005, 6:35:22 AM2/6/05
to
"Rahul Jain" <rj...@nyct.net> a écrit dans le message de news:
87ekfu6...@nyct.net...

> "Christophe Turle" <ctu...@nospam.com> writes:
>
>> No, what i really want is a ->rational at the read time and without
>> reader
>> macros since i don't control inputs :(
>
> You _must_ _not_ _use_ _the_ _lisp_ _reader_, _then_, _because_ _you_
> _are_ _not_ _reading_ _lisp_.
>
> To make it clear: The lisp reader reads lisp code. What you want to read
> is not lisp code. Therefore, you do not want to use the lisp reader.


Yes, i know it's not lisp code. And this is in fact my problem, why IN lisp,
.1111 is read as a float ? yes, the spec is the spec. But for this point,
imho the spec is not good.

I can't satisfy myself thinking that in Lisp .1111 does not mean .1111 (from
human readers point of view)

It's the same as telling you that in language Horrible1 HGF.FDS means .1111
because internally the language uses compression algorithms so it is more
efficient. Where is abstraction ?

Christophe Turle

unread,
Feb 6, 2005, 6:39:16 AM2/6/05
to
"Rahul Jain" <rj...@nyct.net> a écrit dans le message de news:
87is566...@nyct.net...

> "Christophe Turle" <ctu...@nospam.com> writes:
>
>> "Barry Margolin" <bar...@alum.mit.edu> a écrit dans le message de news:
>> barmar-4D7E8B....@comcast.dca.giganews.com...
>>> RATIONALIZE should work with any type of float, not just double-float.
>>
>>
>> i'm afraid not (CLisp 2.33)
>>
>> CL-USER> (rationalize 102.0051)
>> 60081/589
>>
>> CL-USER> (rationalize 102.0051d0)
>> 1020051/10000
>
> I'm afraid so... Please explain how the above is incorrect.


Not sure to understand your reply there.

I didn't want to say that 'rationalize' behave incorrectly. I just showed
that the input type of float matters.

Christophe Turle

unread,
Feb 6, 2005, 7:03:38 AM2/6/05
to
"Rahul Jain" <rj...@nyct.net> a écrit dans le message de news:
87mzui6...@nyct.net...

> "Christophe Turle" <ctu...@nospam.com> writes:
>
>> Is there a Lisp implementation which allows reading 0.11111 as it should
>> ?
>
> All do. Look at the paper on the META parser and just don't convert to
> float in the stage where you compute the value. You'll end up with
> 11111/100000 as you "should".

META : http://home.pipeline.com/~hbaker1/Prag-Parse.html

What i see, is a parser generator which can produce the 0.11111 ->
11111/100000. Ok

So if i understand you well is to read the input string with the generated
parser. This is ok if i thought that my input was application specific.

But what i think is that the lisp reader is flawed. For me, it must
interpret "0.11111" as a rational and not as a float. In all cases ! So my
request is how to hack the lisp reader (even with a specific lisp
implementation) at the 'token' level (i think), so the token "0.11111" is
interpreted as i want it to be.

Christophe Turle

unread,
Feb 6, 2005, 7:12:31 AM2/6/05
to
"William Bland" <new...@abstractnonsense.com> a écrit dans le message de
news: pan.2005.02.05....@abstractnonsense.com...

Seeing digits as macro characters ! Yes, it's a very good idea and it is CL
standard, cool !

thanks for the hack ;)

just to be sure that all cases are handled. For example if input is '3gg', i
have to check this ...

Rahul Jain

unread,
Feb 6, 2005, 7:12:04 AM2/6/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> I didn't want to say that 'rationalize' behave incorrectly. I just showed
> that the input type of float matters.

Of course it does. That much is clear from the description of what it
should do. The issue is that what _you_ want to do is not what it does.
It was suggested as a _possible_ way to solve whatever problem you were
having. The solution you seem to want is to be able to change the lisp
reader to not read lisp any more. Strange goal, if you ask me.

Rahul Jain

unread,
Feb 6, 2005, 7:21:23 AM2/6/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> Yes, i know it's not lisp code. And this is in fact my problem, why IN lisp,
> .1111 is read as a float ? yes, the spec is the spec. But for this point,
> imho the spec is not good.

As you've been told, this point was debated when the spec was being
drawn up, but making .1111 read as a rational would break too much
existing code.

> I can't satisfy myself thinking that in Lisp .1111 does not mean .1111 (from
> human readers point of view)

Humans don't read code. Computers read code. :)

> It's the same as telling you that in language Horrible1 HGF.FDS means .1111
> because internally the language uses compression algorithms so it is more
> efficient. Where is abstraction ?

No it's not. What do you mean by abstraction? The details of the FP
implementation are abstracted. It is allowed to use any base, number of
exponent and mantissa bits, existence of negative zero, NaN(s),
infinities, gradual under/overflow, etc. The last few can't be
determined directly via standard operators, but the others allow a
decent degree of adaptability of code to different FP implementations.

In any case, FP numbers are an important part of computing. More
important than rational numbers, and that's not likely to change in the
future. Too much of the computation done needs to be fast and is based
on approximate, heuristic algorithms or inputs.

Pascal Bourguignon

unread,
Feb 6, 2005, 7:26:32 AM2/6/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> "Rahul Jain" <rj...@nyct.net> a écrit dans le message de news:
> 87ekfu6...@nyct.net...
> > "Christophe Turle" <ctu...@nospam.com> writes:
> >
> >> No, what i really want is a ->rational at the read time and without
> >> reader
> >> macros since i don't control inputs :(
> >
> > You _must_ _not_ _use_ _the_ _lisp_ _reader_, _then_, _because_ _you_
> > _are_ _not_ _reading_ _lisp_.
> >
> > To make it clear: The lisp reader reads lisp code. What you want to read
> > is not lisp code. Therefore, you do not want to use the lisp reader.
>
>
> Yes, i know it's not lisp code. And this is in fact my problem, why IN lisp,
> .1111 is read as a float ? yes, the spec is the spec. But for this point,
> imho the spec is not good.

Because it's read this way by all the other languages, therefore it's
better to keep reading it this way to be able to interchange floating
point data.



> I can't satisfy myself thinking that in Lisp .1111 does not mean .1111 (from
> human readers point of view)

There's a notation in lisp if you really want rationnals: 1111/10000


So we get the best of both: compatible with all the data you can find
everywhere, and still possible to read rationals.


> It's the same as telling you that in language Horrible1 HGF.FDS means .1111
> because internally the language uses compression algorithms so it is more
> efficient. Where is abstraction ?

--
__Pascal Bourguignon__ http://www.informatimago.com/
I need a new toy.
Tail of black dog keeps good time.
Pounce! Good dog! Good dog!

Rahul Jain

unread,
Feb 6, 2005, 7:29:39 AM2/6/05
to
Kent M Pitman <pit...@nhplace.com> writes:

> For example, you could make #\0, #\1, #\2, etc. be readmacros that
> could then read the rest of the number in whatever format they liked.

[...]


> I recall once making a readtable for FORTRAN in which every character in
> the character set was a readmacro that just triggered the FORTRAN parser.

Yikes, Kent! You really scare me sometimes. At least what's needed to
solve this problem doesn't require a huge amount of readtable hacking.
All the digits and the decimal point can be mapped to a readmacro that
simply invokes the parser he needs.

Ingenious, actually!

As a side note, I think he'll want them to be NON-terminating macro
characters, but I don't know the details of the syntax he's reading.

Barry Margolin

unread,
Feb 6, 2005, 8:34:18 AM2/6/05
to
In article <420600fd$0$956$626a...@news.free.fr>,
"Christophe Turle" <ctu...@nospam.com> wrote:

> Yes, i know it's not lisp code. And this is in fact my problem, why IN lisp,
> .1111 is read as a float ? yes, the spec is the spec. But for this point,
> imho the spec is not good.

Why shouldn't it read it as a float? That's the way many dialects of
Lisp have been reading and writing floats for decades, and Common Lisp
was designed to be compatible with preceding dialects like Maclisp where
feasible.

It's also consistent with most other programming languages -- numbers
with embedded decimal points are floating point.

Sure, we could have made .1111 read as a rational, and require you to
write something like .1111e0 to get a float, but why should we have? We
provided another syntax for rationals that didn't conflict with existing
practice -- if you want a rational, type 1111/10000.

Christophe Turle

unread,
Feb 6, 2005, 9:51:35 AM2/6/05
to
"Rahul Jain" <rj...@nyct.net> a écrit dans le message de news:
871xbt7...@nyct.net...

> The solution you seem to want is to be able to change the lisp
> reader to not read lisp any more.
> Strange goal, if you ask me.

Lisp lives.

IF a lisp feature is missing or bad designed, i don't find strange to change
lisp. It will just read NEW lisp.

Of course, you may not agree with the new feature :

0.11111 => read as a rational
0.11111f => read as a float

But that's an other issue ;)

Peter Seibel

unread,
Feb 6, 2005, 9:59:52 AM2/6/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> So if i understand you well is to read the input string with the
> generated parser. This is ok if i thought that my input was
> application specific.

Where is this input coming from?

> But what i think is that the lisp reader is flawed. For me, it must
> interpret "0.11111" as a rational and not as a float. In all cases !

This doesn't make any sense to me. How is it that you have big piles
of Lisp code written in a dialect that is just like Common Lisp except
it expects numbers with a decimal point to be interpreted with a
different syntax?

If you're not talking about Lisp code, then you don't need to change
the Lisp reader, you just need to write a reader that implements the
syntax you want to use when reading whatever these files are that you
have. You can reuse quite a bit of the existing reader, or at least
the functions on top of which it is built (READ-CHAR, INTERN, etc.)

> So my request is how to hack the lisp reader (even with a specific
> lisp implementation) at the 'token' level (i think), so the token
> "0.11111" is interpreted as i want it to be.

That's not possible--the syntax of numbers and symbols is hard wired
into the reader and is not customizable. That

-Peter

--
Peter Seibel pe...@javamonkey.com

Lisp is the red pill. -- John Fraser, comp.lang.lisp

Peter Seibel

unread,
Feb 6, 2005, 10:12:15 AM2/6/05
to
Peter Seibel <pe...@javamonkey.com> writes:

> That's not possible--the syntax of numbers and symbols is hard wired
> into the reader and is not customizable. That

Okay, I spoke too fast--as others have pointed out you can define read
macros on all the digits and the decimal point in order to hijack
this.

-Peter

P.S. I recall some time back I fellow who wanted to read a bunch of
Lisp source that contained package-qualified symbol names without
necessarily defining the packages (He wanted to do some level of
analysis on the source code.) Would this same trick work--define a
read macro on all the consitiuent characters to hijack the
construction of tokens so as to read over colons and handle the
interning of names yourself? I guess it would though without the
package definitions you could lose track of certain
identities--FOO:BAR may be the same as BAR in some contexts, etc.

Christophe Turle

unread,
Feb 6, 2005, 10:22:58 AM2/6/05
to
"Kent M Pitman" <pit...@nhplace.com> a écrit dans le message de news:
umzui3zi...@nhplace.com...

> "Christophe Turle" <ctu...@nospam.com> writes:
>
>> I can't change inputs. I have the string "(x 123.2569 y 1256.3588)" input
>> for example. So i can't introduce reader macros :(
>
> No, that's not so.
> For example, you could make #\0, #\1, #\2, etc. be readmacros that
> could then read the rest of the number in whatever format they liked.

Yes, you are right (I was thinking at pascal #/ reader macro). As written by
william bland, using the digits as reader macros is a good idea.


> Things ONLY mean something in the context of a person (or program)
> creating text in a notation and a person (or program) interpreting that
> text according to a mutually agreed set of rules.


I agree. And the context for Lisp should be compatible with human context.
default float interpretation is not compatible with human reading. That's my
point.


> This may seem obvious but I've got to wonder: Who is making up this text
> that you cannot change?

I have added the parenthesis around a string pasted from a pdf file.

> There is a right time and a wrong time to solve a problem as explained.
>
> It sounds to me like your BEST options are:
>
> (a) to question whether the upstream program shouldn't produce
> 123/1000 instead of .123 if that's what it means

no, it is a copy/paste from a pdf file.

>
> (b) to preprocess the string to change the format from .123 to 123/1000
> before applying the lisp reader

This means parsing two times the input. It is acceptable if the input format
is application specific. But as i said before, 0.1111 shouldn't be read as a
float in Lisp. It is bad design choice.

Did you write 0.123 or 123/1000 in your papers ? Except when speaking about
lisp ;)

Christophe Turle

unread,
Feb 6, 2005, 10:41:53 AM2/6/05
to
"Rahul Jain" <rj...@nyct.net> a écrit dans le message de news:
87wttl6...@nyct.net...

> "Christophe Turle" <ctu...@nospam.com> writes:
>
>> Yes, i know it's not lisp code. And this is in fact my problem, why IN
>> lisp,
>> .1111 is read as a float ? yes, the spec is the spec. But for this point,
>> imho the spec is not good.
>
> As you've been told, this point was debated when the spec was being
> drawn up, but making .1111 read as a rational would break too much
> existing code.

Once again this old good reason (like with all in upper case) ;)

(let ((*read-rational-as* :float))
(load "your-library") )


>> I can't satisfy myself thinking that in Lisp .1111 does not mean .1111
>> (from
>> human readers point of view)
>
> Humans don't read code. Computers read code. :)

sorry, but humans read and write code a lot ;)

>> It's the same as telling you that in language Horrible1 HGF.FDS means
>> .1111
>> because internally the language uses compression algorithms so it is more
>> efficient. Where is abstraction ?
>
> No it's not. What do you mean by abstraction? The details of the FP
> implementation are abstracted.

But the number implementation is not. In this case, you tell that numbers
must be represented as float.

> Too much of the computation done needs to be fast and is based
> on approximate, heuristic algorithms or inputs.

You can (by compiler/macros) go from rational to float but you can't go the
way back ! It's why it is better to read (by default) as rational and
further optimize your code.

Christophe Turle

unread,
Feb 6, 2005, 11:00:38 AM2/6/05
to
"Pascal Bourguignon" <sp...@mouse-potato.com> a écrit dans le message de
news: 87mzuhc...@thalassa.informatimago.com...

> "Christophe Turle" <ctu...@nospam.com> writes:
>
>> "Rahul Jain" <rj...@nyct.net> a écrit dans le message de news:
>> 87ekfu6...@nyct.net...
>> > "Christophe Turle" <ctu...@nospam.com> writes:
>> >
>> >> No, what i really want is a ->rational at the read time and without
>> >> reader
>> >> macros since i don't control inputs :(
>> >
>> > You _must_ _not_ _use_ _the_ _lisp_ _reader_, _then_, _because_ _you_
>> > _are_ _not_ _reading_ _lisp_.
>> >
>> > To make it clear: The lisp reader reads lisp code. What you want to
>> > read
>> > is not lisp code. Therefore, you do not want to use the lisp reader.
>>
>>
>> Yes, i know it's not lisp code. And this is in fact my problem, why IN
>> lisp,
>> .1111 is read as a float ? yes, the spec is the spec. But for this point,
>> imho the spec is not good.
>
> Because it's read this way by all the other languages,
> therefore it's
> better to keep reading it this way to be able to interchange floating
> point data.

as said in an other post :

(let ((*read-rational-as* :float))
(load "my-data") )

It is not because other languages have bad design that lisp must do the
same.

>> I can't satisfy myself thinking that in Lisp .1111 does not mean .1111
>> (from
>> human readers point of view)
>
> There's a notation in lisp if you really want rationnals: 1111/10000

Humans write/read 0.1111 not 1111/10000. Of course you may add EACH time a
layer to convert "0.1111" to "1111/10000" but what a burden ! don't even
think about using the REPL :(

You express numbers as rational and MAY implement them with floats.

> So we get the best of both: compatible with all the data you can find
> everywhere, and still possible to read rationals.

CL-USER> (read-from-string "0.11111111101111111")
0.11111111

Are you sure this is the best ? sure that this never leads to errors in app
? sure that if showed to humans, the majority will say "that's fine" ?

Floats should be kept for specialists/compilers ... and surely not as a
default language parsing behavior.

Christophe Turle

unread,
Feb 6, 2005, 11:14:03 AM2/6/05
to
"Barry Margolin" <bar...@alum.mit.edu> a écrit dans le message de news:
barmar-AB359E....@comcast.dca.giganews.com...

> In article <420600fd$0$956$626a...@news.free.fr>,
> "Christophe Turle" <ctu...@nospam.com> wrote:
>
>> Yes, i know it's not lisp code. And this is in fact my problem, why IN
>> lisp,
>> .1111 is read as a float ? yes, the spec is the spec. But for this point,
>> imho the spec is not good.
>
> Why shouldn't it read it as a float? That's the way many dialects of
> Lisp have been reading and writing floats for decades, and Common Lisp
> was designed to be compatible with preceding dialects like Maclisp where
> feasible.

Just toggle parsing behavior to keep these damned compatibilies.

> It's also consistent with most other programming languages -- numbers
> with embedded decimal points are floating point.

Just toggle parsing behavior to read all these low-level languages inputs.

> Sure, we could have made .1111 read as a rational, and require you to
> write something like .1111e0 to get a float, but why should we have? We
> provided another syntax for rationals that didn't conflict with existing
> practice -- if you want a rational, type 1111/10000.

Because these practices are bad. And i don't want to write 1111/10000
instead of .1111, it is not human conventional. It is just implementation
details.

Of course we can write rationals this way. We can also program in assembler
all applications. After all, it was THE practice some years ago.

Christophe Rhodes

unread,
Feb 6, 2005, 11:12:32 AM2/6/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> I agree. And the context for Lisp should be compatible with human context.
> default float interpretation is not compatible with human reading. That's my
> point.

If that's your point, it's not a very good one. I am a human (I know,
I know, I could be a dog); I read Lisp quite a lot, and I can
interpret the notation of tokens as floating point numbers.

I actually don't believe that the solution to the "Naïve Reader"
problem is to force everyone to descend to the level of Most Common
Naïveté; instead, I'd suggest that the naïve reader use this to
educate themselves.

Christophe

Christophe Rhodes

unread,
Feb 6, 2005, 11:17:32 AM2/6/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> Because these practices are bad. And i don't want to write 1111/10000
> instead of .1111, it is not human conventional. It is just implementation
> details.

This is just silly, now. In my daily work, if I write 0.1111, I imply
something different from if I write 1111/10000, and the community with
which I communicate understands this distinction. (It isn't quite the
same distinction as the distinction that the default Lisp reader
draws, but it is prety close.) You seem to be implying that your
personal vocabulary is somehow the unique "human convention" -- and,
I'm sorry to have to tell you, it isn't.

Christophe

Christophe Turle

unread,
Feb 6, 2005, 11:29:45 AM2/6/05
to
"Peter Seibel" <pe...@javamonkey.com> a écrit dans le message de news:
m3oeexe...@javamonkey.com...

> "Christophe Turle" <ctu...@nospam.com> writes:
>
> Where is this input coming from?
>
> This doesn't make any sense to me. How is it that you have big piles
> of Lisp code written in a dialect that is just like Common Lisp except
> it expects numbers with a decimal point to be interpreted with a
> different syntax?

I do a copy/paste from tables in pdf files. To be more precise these tables
map channel numbers to frequencies. It is used in TV monitoring app. After
that i enclosed the paste between "( and ")

The only thing to do is to read this and interpret this in the good
structures. The problem is that Lisp number interpretation is not compatible
with human one. And i think that this is a bad design choice.

Christophe Turle

unread,
Feb 6, 2005, 11:49:19 AM2/6/05
to
"Christophe Rhodes" <cs...@cam.ac.uk> a écrit dans le message de news:
sqpszdi...@cam.ac.uk...

> "Christophe Turle" <ctu...@nospam.com> writes:
>
>> I agree. And the context for Lisp should be compatible with human
>> context.
>> default float interpretation is not compatible with human reading. That's
>> my
>> point.
>
> If that's your point, it's not a very good one. I am a human (I know,
> I know, I could be a dog); I read Lisp quite a lot, and I can
> interpret the notation of tokens as floating point numbers.

'human context' means humans in general. How many % of documents written by
humans which include 0.1111111 to be interpreted as a float ?

And even within programmers, what is the % of them that really need the
knowledge of float if they were given the rational choice ? the vast
majority of Applications don't need float to be written. It is just usefull
at the optimization stage.

> I actually don't believe that the solution to the "Naïve Reader"
> problem is to force everyone to descend to the level of Most Common
> Naïveté;

not "naive reader", right abstract level reader.

> instead, I'd suggest that the naïve reader use this to
> educate themselves.

And why not TV users knowing about quantum theory ? ok it's extreme, but it
is to better show my point ;-)

Christophe Turle

unread,
Feb 6, 2005, 11:59:39 AM2/6/05
to
"Christophe Rhodes" <cs...@cam.ac.uk> a écrit dans le message de news:
sqlla1i...@cam.ac.uk...

it is.

Your community is not human community it is a subset of it.

want a proof ?

> "if I write 0.1111, I imply something different from if I write
> 1111/10000"

I bet that the vast majority of humans don't agree with your sentence and
will tell you the contrary. When they write 0.1111 they mean 1111/10000.

Cameron MacKinnon

unread,
Feb 6, 2005, 12:23:56 PM2/6/05
to
Christophe Rhodes wrote:
> "Christophe Turle" <ctu...@nospam.com> writes:
>
>
>> I agree. And the context for Lisp should be compatible with human
>> context. default float interpretation is not compatible with human
>> reading. That's my point.
>
>
> If that's your point, it's not a very good one. I am a human (I
> know, I know, I could be a dog); I read Lisp quite a lot, and I can
> interpret the notation of tokens as floating point numbers.

I doubt that you can look at any given number and compute in your head
the error that will be introduced if converted to a binary single or
double float. Or by "interpret" do you just mean that you know the
number will be perturbed as it is read into memory, and you're OK with that?

> I actually don't believe that the solution to the "Naïve Reader"
> problem is to force everyone to descend to the level of Most Common
> Naïveté; instead, I'd suggest that the naïve reader use this to
> educate themselves.

Your view of software engineering, to wit giving the user sharp tools
that don't work the way a numerate amateur would expect, then waiting
for him to discover that they're dangerous and broken, has led and will
continue to lead to disasters large and small, along with miscellaneous
annoyingly unreliable systems. Other threads here have recently shown
that essentially nobody, even those attending the world's best computer
science schools, gets mandatory instruction in the the mysteries of the
binary floats that programmers use every day. What event led to your
education in these matters?

> This is just silly, now. In my daily work, if I write 0.1111, I
> imply something different from if I write 1111/10000, and the
> community with which I communicate understands this distinction. (It
> isn't quite the same distinction as the distinction that the default
> Lisp reader draws, but it is prety close.) You seem to be implying
> that your personal vocabulary is somehow the unique "human
> convention" -- and, I'm sorry to have to tell you, it isn't.

What do you and the other humans you interact with interpret 0.1111 as
meaning? Is there an implied +/-0.00005? An implied
+/-0.00000000000000005? It seems to me that you're already admitting
that your computer doesn't interpret your 0.1111 in the same way as the
people in your field do. Do your programs take steps to interpret 0.1111
differently from the way Common Lisp normally would? Or do they just do
the wrong thing (according to your community's conventions) and produce
questionable output whose error is not quantified?

Christopher C. Stacy

unread,
Feb 6, 2005, 12:25:31 PM2/6/05
to
Can you show us some code in the other programming language(s)
to which you are referring in which numbers with a decimal point
do not indicate a floating point number?

By the way, what TV channel frequencies are you being handed
that are not conveniently represented by floating point?

Christophe Rhodes

unread,
Feb 6, 2005, 12:43:34 PM2/6/05
to
Cameron MacKinnon <cmack...@clearspot.net> writes:

> Christophe Rhodes wrote:
>> "Christophe Turle" <ctu...@nospam.com> writes:
>> If that's your point, it's not a very good one. I am a human (I
>> know, I know, I could be a dog); I read Lisp quite a lot, and I can
>> interpret the notation of tokens as floating point numbers.
>
> I doubt that you can look at any given number and compute in your head
> the error that will be introduced if converted to a binary single or
> double float.

Doubt, by all means. I don't think it's that hard, but I'll happily
concede that it's not what I typically do.

> Or by "interpret" do you just mean that you know the number will be
> perturbed as it is read into memory, and you're OK with that?

If there is an exact number which, for some reason or other, is going
to be used in a computer calculation as a floating point number, then
the act of reading it in will introduce a source of error (to be
accounted for along with all the other sources of error in the
experiment). It's not the disaster that people in this thread seem to
be thinking it is, as long as the error is quantified and verified to
be small in comparison with other sources of error, which it often --
though of course not always -- is.

>> I actually don't believe that the solution to the "Naïve Reader"
>> problem is to force everyone to descend to the level of Most Common
>> Naïveté; instead, I'd suggest that the naïve reader use this to
>> educate themselves.
>
> Your view of software engineering, to wit giving the user sharp tools
> that don't work the way a numerate amateur would expect, then waiting
> for him to discover that they're dangerous and broken, has led and will
> continue to lead to disasters large and small, along with miscellaneous
> annoyingly unreliable systems.

I'm quite happy for other people to be kept away from the knives,
though I'd continue to encourage them to learn how to use knives
safely, because if they do they will be able to produce nice sushi.

> Other threads here have recently shown that essentially nobody, even
> those attending the world's best computer science schools, gets
> mandatory instruction in the the mysteries of the binary floats that
> programmers use every day. What event led to your education in these
> matters?

No "event" led to my education in these matters, unless you count my
being born. Maybe I had the good fortune to be in an environment
where knowledge was prized rather than dismissed or viewed simply as a
means to a paycheque. (I'm not a computer scientist by training;
while I was studying Physics, those who were learning Computer Science
learnt about floating point representations and Numerical Analysis as
part of their degree, and this hasn't changed.)

>> This is just silly, now. In my daily work, if I write 0.1111, I
>> imply something different from if I write 1111/10000, and the
>> community with which I communicate understands this distinction. (It
>> isn't quite the same distinction as the distinction that the default
>> Lisp reader draws, but it is prety close.) You seem to be implying
>> that your personal vocabulary is somehow the unique "human
>> convention" -- and, I'm sorry to have to tell you, it isn't.
>
> What do you and the other humans you interact with interpret 0.1111 as
> meaning? Is there an implied +/-0.00005? An implied
> +/-0.00000000000000005?

The first is closer, but then again I suspect we would be using +/-
with different meanings.

0.1111 as is would be something like "this number has been observed as
being about 1111/10000, and we don't have any justification for any
more significance".

0.1111 +/- 0.00005 means something subtly different: "a quantity has
been measured to be 1111/10000, and experiments suggest that the
true value of the quantity has about a 60% chance of lying within
5/100000 of the measured value".

And "1111/10000" means "exactly 1111/10000, from some theoretical
calculation".

> It seems to me that you're already admitting that your computer
> doesn't interpret your 0.1111 in the same way as the people in your
> field do. Do your programs take steps to interpret 0.1111
> differently from the way Common Lisp normally would? Or do they just
> do the wrong thing (according to your community's conventions) and
> produce questionable output whose error is not quantified?

If I'm reporting a scientific result, of course I take the care to
compute an error estimate. Not to do such would not only be
irresponsible, it would result in my work not being published, or if
published it would either be ignored or be rebutted.

Christophe

Dan Muller

unread,
Feb 6, 2005, 12:50:06 PM2/6/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> "Christophe Rhodes" <cs...@cam.ac.uk> a écrit dans le message de news:
> sqpszdi...@cam.ac.uk...
>> "Christophe Turle" <ctu...@nospam.com> writes:
>>
>>> I agree. And the context for Lisp should be compatible with human
>>> context.
>>> default float interpretation is not compatible with human reading. That's
>>> my
>>> point.

This is just silly. It's a programming convention that has held over a
long time and in many programming languages. The notation is for
programmers, not end users. It's good that Lisp follows convention in
this particular, it's less surprising for prorgrammers. Just as in any
programming language, if you want different conventions in your user
interface, you provide them by writing code.

>>
>> If that's your point, it's not a very good one. I am a human (I know,
>> I know, I could be a dog); I read Lisp quite a lot, and I can
>> interpret the notation of tokens as floating point numbers.
>
> 'human context' means humans in general. How many % of documents written by
> humans which include 0.1111111 to be interpreted as a float ?

Since most non-computer users don't know what "float" is, probably
almost none, of course. The question isn't relevant. But in reading
scientific papers, I would normally assume that numbers written this
way are approximate, unless otherwise specified, which is an
assumption that is similar to assuming a data type of "float".

----
Dan Muller
email: (reverse "moc.liamekaens@20sd89dti")

Christophe Turle

unread,
Feb 6, 2005, 2:32:15 PM2/6/05
to
"Christopher C. Stacy" <cst...@news.dtpq.com> a écrit dans le message de
news: uhdkps...@news.dtpq.com...

> Can you show us some code in the other programming language(s)
> to which you are referring in which numbers with a decimal point
> do not indicate a floating point number?

Perhaps some exists, but i don't know about. But it's not a sufficient
reason why it should be like this. Reasons must be objective ones not
'follow others' ones.


> By the way, what TV channel frequencies are you being handed
> that are not conveniently represented by floating point?

(rationalize 201.0053) ; in MHz
=> 37990/189

It works with double float. But the point is : why MUST i care about float
type EVEN if i'm not concerned with optimization ???

Peter Seibel

unread,
Feb 6, 2005, 2:38:19 PM2/6/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> "Christopher C. Stacy" <cst...@news.dtpq.com> a écrit dans le

>> By the way, what TV channel frequencies are you being handed


>> that are not conveniently represented by floating point?
>
> (rationalize 201.0053) ; in MHz
> => 37990/189

So what's the problem?

(float (rationalize 201.0053)) ==> 201.0053

And you do know about this, right:

(let ((*read-default-float-format* 'double-float))
(rationalize (read-from-string "201.0053"))) ==> 2010053/10000

-Peter

Christophe Turle

unread,
Feb 6, 2005, 2:52:41 PM2/6/05
to
"Dan Muller" <itd9...@sneakemail.com> a écrit dans le message de news:
iNsNd.1860$ng6...@newssvr17.news.prodigy.com...

> "Christophe Turle" <ctu...@nospam.com> writes:
>
>> "Christophe Rhodes" <cs...@cam.ac.uk> a écrit dans le message de news:
>> sqpszdi...@cam.ac.uk...
>>> "Christophe Turle" <ctu...@nospam.com> writes:
>>>
>>>> I agree. And the context for Lisp should be compatible with human
>>>> context.
>>>> default float interpretation is not compatible with human reading.
>>>> That's
>>>> my
>>>> point.
>
> This is just silly.

thx ;)

> It's a programming convention that has held over a
> long time and in many programming languages.

And what ? it is sufficient for you to be convinced. not me.

> The notation is for programmers, not end users.

Even for programmers this is bad choice. From my programming experience
within different contexts, i have seen that programmers use floats like
rationals. Of course, this causes some problems which should have been
avoided if only rational numbers have been at hand.

Don't misunderstand me : float are useful but just for an optimization
purpose. So with app using lots of number computation, i'm sure that
programmers have to know how to use floats. But for the rest, and they are
the large majority of App, you don't need them, if an other choice were
given. It's why rationals should be the DEFAULT reader choice.


>>> If that's your point, it's not a very good one. I am a human (I know,
>>> I know, I could be a dog); I read Lisp quite a lot, and I can
>>> interpret the notation of tokens as floating point numbers.
>>
>> 'human context' means humans in general. How many % of documents written
>> by
>> humans which include 0.1111111 to be interpreted as a float ?
>
> Since most non-computer users don't know what "float" is, probably
> almost none, of course. The question isn't relevant. But in reading
> scientific papers, I would normally assume that numbers written this
> way are approximate, unless otherwise specified, which is an
> assumption that is similar to assuming a data type of "float".

Scientifics programs are not the preponderant part of programs in the world.

Cameron MacKinnon

unread,
Feb 6, 2005, 2:59:24 PM2/6/05
to
Christophe Rhodes wrote:
> If there is an exact number which, for some reason or other, is going
> to be used in a computer calculation as a floating point number,
> then the act of reading it in will introduce a source of error (to be
> accounted for along with all the other sources of error in the
> experiment). It's not the disaster that people in this thread seem
> to be thinking it is, as long as the error is quantified and verified
> to be small in comparison with other sources of error, which it
> often -- though of course not always -- is.

It's not even USUALLY a disaster in common practice (which is to say,
when no error analysis is done). The most insidious thing about floating
point is that it can be abused horribly and still give good results
99.99% of the time. And so, of course, most everyone abuses it horribly.
Occasionally there's a disaster. One can google for "floating
point"+disaster. Patriot missile malfunction kills 28, anyone?

> No "event" led to my education in these matters, unless you count my
> being born. Maybe I had the good fortune to be in an environment
> where knowledge was prized rather than dismissed or viewed simply as
> a means to a paycheque. (I'm not a computer scientist by training;
> while I was studying Physics, those who were learning Computer
> Science learnt about floating point representations and Numerical
> Analysis as part of their degree, and this hasn't changed.)

Your alma mater's CS department seems exceptional in that regard. When I
learned about FP it was done in software (on all the equipment available
to me) and implementing one's own fixed point representation to meet
given speed and accuracy targets wasn't unusual. This naturally led to
more awareness about the costs and benefits of floating point.

>> It seems to me that you're already admitting that your computer
>> doesn't interpret your 0.1111 in the same way as the people in your
>> field do. Do your programs take steps to interpret 0.1111
>> differently from the way Common Lisp normally would? Or do they
>> just do the wrong thing (according to your community's conventions)
>> and produce questionable output whose error is not quantified?
>
>
> If I'm reporting a scientific result, of course I take the care to
> compute an error estimate. Not to do such would not only be
> irresponsible, it would result in my work not being published, or if
> published it would either be ignored or be rebutted.

Well, you have a better understanding of the representation than the
vast majority of computer users. I hope that you're never burned by a
calculation you make whose error estimate (which you won't compute,
because the work isn't for publication, or is only a "back of the
envelope" calculation) ends up far higher than thought, spoiling your
answers undetected. I wish more coders (or their tools) were as
conscientious as you are.

Kent M Pitman

unread,
Feb 6, 2005, 2:59:59 PM2/6/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> "Christopher C. Stacy" <cst...@news.dtpq.com> a écrit dans le message de
> news: uhdkps...@news.dtpq.com...
> > Can you show us some code in the other programming language(s)
> > to which you are referring in which numbers with a decimal point
> > do not indicate a floating point number?
>
> Perhaps some exists, but i don't know about. But it's not a sufficient
> reason why it should be like this. Reasons must be objective ones not
> 'follow others' ones.

Fair enough. Please just give an "objective" description of the term
"objective" and we'll be all set.

One might, for example, argue that objective and subjective differ
only in that the subjectivity in the former is embedded so
fundamentally in the design of the universe that it is no longer
subject to change. That is, certain numeric constants and
relationships may have at one point in the design of the Universe been
variables, but once other things were nailed down, they no longer
could be.

Floating point is very close to this in the computer world, given that
there is floating point hardware on nearly every machine, and decades of
history involving thousands, perhaps even millions, of programmers who
are familiar with the "meaning" of 0.11111 in computerese.

As such, I would take Chris's question as an attempt to be objective,
that is, to say that the existing mechanism and notation serves a nearly
ubiquitous aspect of both notation and implementation that transcends
programming languages and is not likely to change any time in the next
year or two, nor probably much longer. That's a good floating point
approximation to "objective" in my book...



> > By the way, what TV channel frequencies are you being handed
> > that are not conveniently represented by floating point?
>
> (rationalize 201.0053) ; in MHz
> => 37990/189
>
> It works with double float. But the point is : why MUST i care about float
> type EVEN if i'm not concerned with optimization ???

You don't have to at all. If you're not concerned about optimization,
you're free to write and advertise a BCD library with appropriate readers
and/or readmacros.

What you ARE obliged to do is to write code that is not there by default.
Lisp enables you to do many things, but one of the things you are not enabled
to do is to wish for things and have them come into existence without
any work.

Maybe you just want Scheme. In Scheme, they have an extra dimension
of notational terminology for numbers--exactness vs inexactness
(orthogonally to floating point vs integer, such that you can have
exact floats and inexact integers).

Cameron MacKinnon

unread,
Feb 6, 2005, 3:09:48 PM2/6/05
to
Dan Muller wrote:

[regarding floating point numbers]

> This is just silly. It's a programming convention that has held over
> a long time and in many programming languages. The notation is for
> programmers, not end users.

You don't really believe this, do you? The notation convention dates
from when users did their own programming. And the underlying
representation's accuracy and range was obviously designed to represent
physical world quantities rather than the sort of numbers that pure
computer scientists might have a use for. It's not like floating point
is a useful tool that programmers generally use to build numeric
representations whose accuracy and range are appropriate for the problem
at hand. The representation was designed for the end user, back in the
day when the end user was almost always a hard scientist calculating
using imprecise physical world measurements.

Christophe Turle

unread,
Feb 6, 2005, 3:13:43 PM2/6/05
to
"Peter Seibel" <pe...@javamonkey.com> a écrit dans le message de news:
m3zmyhc...@javamonkey.com...

> "Christophe Turle" <ctu...@nospam.com> writes:
>
>> "Christopher C. Stacy" <cst...@news.dtpq.com> a écrit dans le
>
>>> By the way, what TV channel frequencies are you being handed
>>> that are not conveniently represented by floating point?
>>
>> (rationalize 201.0053) ; in MHz
>> => 37990/189
>
> So what's the problem?
>
> (float (rationalize 201.0053)) ==> 201.0053

the problem is that i want to print the value as a HZ value so :

(my-print-fct (read-from-string "201.0053"))
=> "201005300"

without float burden it should have simply been :

(defun my-print-fct ( in-Mhz )
(format nil "~d" (* 1000000 in-Mhz)) )

i'm waiting for your solution.


>
> And you do know about this, right:
>
> (let ((*read-default-float-format* 'double-float))
> (rationalize (read-from-string "201.0053"))) ==> 2010053/10000
>

You cheat there ! what you do is taking a more precise float type, so :

- you use float as a rational.
- an other input value may not work (of course one not from your test
cases). And there begin hidden errors hard to detect... So using
rationalize/double-float won't be taken as a valid solution for my-print-fct
;)

Coby Beck

unread,
Feb 6, 2005, 3:15:05 PM2/6/05
to
"Christophe Rhodes" <cs...@cam.ac.uk> wrote in message
news:sqekfti...@cam.ac.uk...

> Cameron MacKinnon <cmack...@clearspot.net> writes:
>> What do you and the other humans you interact with interpret 0.1111 as
>> meaning? Is there an implied +/-0.00005? An implied
>> +/-0.00000000000000005?
>
> The first is closer, but then again I suspect we would be using +/-
> with different meanings.
>
> 0.1111 as is would be something like "this number has been observed as
> being about 1111/10000, and we don't have any justification for any
> more significance".
>
> 0.1111 +/- 0.00005 means something subtly different: "a quantity has
> been measured to be 1111/10000, and experiments suggest that the
> true value of the quantity has about a 60% chance of lying within
> 5/100000 of the measured value".
>
> And "1111/10000" means "exactly 1111/10000, from some theoretical
> calculation".

Well, since I pass the test of being human I will offer yet another
interpretation. When I saw .1111 the first time a few posts back I saw 1/9
among the other suggested interpretations.

Is this Wrong with a capital W? No, it is not because data is nothing
without context.

The basic fallacy of the "don't double-float my boat" camp is that a number,
absent application context, is as meaningless as the ASCII codes of the
characters in its representation. There is no reason, absent that context,
to believe that the best interpretation of .123 is 123/100. Not only that,
I completely reject the notion that a naive human who types at a terminal
".123" most probably means 123/100. I suggest that in ~99/100% of
non-computer scientist cases, the naive user does not even know what they
really mean and in nearly as many, would not care. In computer professional
cases it may well be quite high as well. Even if not, it is very probable
that in 90% of cases it will not matter.

As for the smaller number of times that it does matter, no amount of
machinary can remove the obligation from the programmer to use the correct
programming techniques nor from the user to understand the context of the
numbers they read.

I am a bit mystified as to why the other side of this equation is being
ignored, that is the writing part of reading and writing data. If your
program produces 123/100 and you write it to a file as .123, then this is
where the bug is hatched.

--
Coby Beck
(remove #\Space "coby 101 @ big pond . com")


Marc Battyani

unread,
Feb 6, 2005, 3:33:41 PM2/6/05
to

"Christophe Turle" <ctu...@nospam.com> wrote

> the problem is that i want to print the value as a HZ value so :
>
> (my-print-fct (read-from-string "201.0053"))
> => "201005300"
>
> without float burden it should have simply been :
>
> (defun my-print-fct ( in-Mhz )
> (format nil "~d" (* 1000000 in-Mhz)) )

I didn't followed this thread so may be out of context but I would do this:
(format nil "~d" (round 201.0053 0.000001))
=>"201005300"

Assuming you want an integer number of Hz

Marc


Christophe Turle

unread,
Feb 6, 2005, 3:37:01 PM2/6/05
to
"Kent M Pitman" <pit...@nhplace.com> a écrit dans le message de news:
uu0op4...@nhplace.com...

> "Christophe Turle" <ctu...@nospam.com> writes:
>
>> "Christopher C. Stacy" <cst...@news.dtpq.com> a écrit dans le message de
>> news: uhdkps...@news.dtpq.com...
>> > Can you show us some code in the other programming language(s)
>> > to which you are referring in which numbers with a decimal point
>> > do not indicate a floating point number?
>>
>> Perhaps some exists, but i don't know about. But it's not a sufficient
>> reason why it should be like this. Reasons must be objective ones not
>> 'follow others' ones.
>
> Fair enough. Please just give an "objective" description of the term
> "objective" and we'll be all set.

It is sufficient to say that we agree that this reason was NOT objective.

> Floating point is very close to this in the computer world, given that
> there is floating point hardware on nearly every machine,

Better and better. How didn't i think of it sooner ? I have to write my app
with floats because hardware use them ;)

> and decades of
> history involving thousands, perhaps even millions, of programmers who
> are familiar with the "meaning" of 0.11111 in computerese.

Sorry to don't write buggy, time consuming App because 'millions' of people
knows float theory. It's not because lots of people know assembler languages
that i will use them.

> As such, I would take Chris's question as an attempt to be objective,
> that is, to say that the existing mechanism and notation serves a nearly
> ubiquitous aspect of both notation and implementation that transcends
> programming languages and is not likely to change any time in the next
> year or two, nor probably much longer. That's a good floating point
> approximation to "objective" in my book...

True thing is to know what will win at last not during the next year.
Natural selection works even for programming language. I just hope we won't
be dead at this time.

>> > By the way, what TV channel frequencies are you being handed
>> > that are not conveniently represented by floating point?
>>
>> (rationalize 201.0053) ; in MHz
>> => 37990/189
>>
>> It works with double float. But the point is : why MUST i care about
>> float
>> type EVEN if i'm not concerned with optimization ???
>
> You don't have to at all. If you're not concerned about optimization,
> you're free to write and advertise a BCD library with appropriate readers
> and/or readmacros.

Yes, surely the way to go.

> Maybe you just want Scheme. In Scheme, they have an extra dimension
> of notational terminology for numbers--exactness vs inexactness
> (orthogonally to floating point vs integer, such that you can have
> exact floats and inexact integers).

Perhaps, i will look at it.

Christophe Turle

unread,
Feb 6, 2005, 3:46:28 PM2/6/05
to
"Marc Battyani" <Marc.B...@fractalconcept.com> a écrit dans le message
de news: cu5uup$3...@library2.airnews.net...

>
> "Christophe Turle" <ctu...@nospam.com> wrote
>
>> the problem is that i want to print the value as a HZ value so :
>>
>> (my-print-fct (read-from-string "201.0053"))
>> => "201005300"
>>
>> without float burden it should have simply been :
>>
>> (defun my-print-fct ( in-Mhz )
>> (format nil "~d" (* 1000000 in-Mhz)) )
>
> I didn't followed this thread so may be out of context but I would do
> this:
> (format nil "~d" (round 201.0053 0.000001))
> =>"201005300"
>

with CLisp 2.33.1, it gives :

CL-USER> (format nil "~d" (round 201.0053 0.000001))
"201005296"

I hope my version of clisp is buggy with additions of mine, else it proves
that even for simple things like this, errors are easy with floats.

Christophe Rhodes

unread,
Feb 6, 2005, 3:44:57 PM2/6/05
to
Cameron MacKinnon <cmack...@clearspot.net> writes:

> Christophe Rhodes wrote:
>>> It seems to me that you're already admitting that your computer
>>> doesn't interpret your 0.1111 in the same way as the people in your
>>> field do. Do your programs take steps to interpret 0.1111
>>> differently from the way Common Lisp normally would? Or do they
>>> just do the wrong thing (according to your community's conventions)
>>> and produce questionable output whose error is not quantified?
>> If I'm reporting a scientific result, of course I take the care to
>> compute an error estimate. Not to do such would not only be
>> irresponsible, it would result in my work not being published, or if
>> published it would either be ignored or be rebutted.
>
> Well, you have a better understanding of the representation than the
> vast majority of computer users. I hope that you're never burned by a
> calculation you make whose error estimate (which you won't compute,
> because the work isn't for publication, or is only a "back of the
> envelope" calculation) ends up far higher than thought, spoiling your
> answers undetected.

Lest anyone get the wrong impression, I'm sure I've made a few
mistakes... but maybe too few to mention.

> I wish more coders (or their tools) were as conscientious as you
> are.

So do I. So do I.

Christophe

Cameron MacKinnon

unread,
Feb 6, 2005, 3:52:42 PM2/6/05
to
Kent M Pitman wrote:
> Floating point is very close to [being fundamentally embedded] in the

> computer world, given that there is floating point hardware on nearly
> every machine, and decades of history involving thousands, perhaps
> even millions, of programmers who are familiar with the "meaning" of
> 0.11111 in computerese.

I suspect that of all the people who have ever written floating point
code (and here I'll be generous and exclude mere spreadsheet users),
fewer than half of them even realized that the representation was
inexact, and perhaps one in fifty understood enough to be wary of the
pitfalls.

There was perhaps a time when the majority of users of general purpose
FP hardware wanted inexact math without error bounds calculation by
default -- i.e they were willing to live with the occasional need for
numerical analysis and the odd model blowing up because they couldn't
afford the cycles or the gates to compute cumulative errors along with
their shady numbers. That time is long past, I think.

> What you ARE obliged to do is to write code that is not there by
> default. Lisp enables you to do many things, but one of the things
> you are not enabled to do is to wish for things and have them come
> into existence without any work.

True... That's what c.l.l is for! The original poster got helpful code
and suggestions, but also, disturbingly, comments to the effect that
yes, Lisp is a programmable programming language, but you shouldn't
program it THAT way.

Christophe Turle

unread,
Feb 6, 2005, 4:04:23 PM2/6/05
to
"Coby Beck" <cb...@mercury.bc.ca> a écrit dans le message de news:
dVuNd.14567$tU6.6609@edtnps91...

>
> Well, since I pass the test of being human I will offer yet another
> interpretation. When I saw .1111 the first time a few posts back I saw
> 1/9
> among the other suggested interpretations.
>
> Is this Wrong with a capital W? No, it is not because data is nothing
> without context.
> The basic fallacy of the "don't double-float my boat" camp is that a
> number, absent application context, is as meaningless as the ASCII codes
> of the characters in its representation. There is no reason, absent that
> context, to believe that the best interpretation of .123 is 123/100.

Yes and No. When you don't specify context the default one apply so there is
a context.

Now, what is the default context when humans see ".12455". I argue that it
means 12455/100000. I even argue that for the most part, programmers it
means the same thing. And even for float intensive users, this means that
when they see it on a price ticket ;)

> Not only that, I completely reject the notion that a naive human who
> types at a terminal ".123" most probably means 123/100.

You reject evidence : ask your wife if she interprets 0.1 the same as 1/10.
I bet the answer is yes.


> I suggest that in ~99/100% of

Do you mean 99% ??? i suspect a typo there which is important for the rest
of the comprehension.

> non-computer scientist cases, the naive user does not even know what they
> really mean and in nearly as many, would not care. In computer
> professional cases it may well be quite high as well. Even if not, it is
> very probable that in 90% of cases it will not matter.
>
> As for the smaller number of times that it does matter, no amount of
> machinary can remove the obligation from the programmer to use the correct
> programming techniques nor from the user to understand the context of the
> numbers they read.
>
> I am a bit mystified as to why the other side of this equation is being
> ignored, that is the writing part of reading and writing data. If your
> program produces 123/100 and you write it to a file as .123, then this is
> where the bug is hatched.

"0.123" is the more human common way to write 123/100. No bugs there.

Coby Beck

unread,
Feb 6, 2005, 4:10:27 PM2/6/05
to

"Christophe Turle" <ctu...@nospam.com> wrote in message
news:42064cff$0$951$626a...@news.free.fr...

> "Christophe Rhodes" <cs...@cam.ac.uk> a écrit dans le message de news:
> sqlla1i...@cam.ac.uk...
>> draws, but it is prety close.) You seem to be implying that your
>> personal vocabulary is somehow the unique "human convention" -- and,
>> I'm sorry to have to tell you, it isn't.
>
> it is.
>

Hi, Christopher, sorry to be "ganging up" on you here but you appear to be
using mostly argument by consensus here so I will just add that I too, am
human and do not agree that .1111 means 1111/10000 by default.

> Your community is not human community it is a subset of it.

> want a proof ?

This i would like to see!
But an interesting experiment might be a multiple choice question you could
give to different sets of people:

What does .1111 mean?

a) .1111d0
b) 1111/10000
c) 1.111x10e-4
d) all of the above

I'd wager that the vast majority of groups polled would select d or not
understand the question. Of those who understood the notational differences
you would get a split between d and "can't answer this trick question,
sorry"

>> "if I write 0.1111, I imply something different from if I write
>> 1111/10000"
>
> I bet that the vast majority of humans don't agree with your sentence and
> will tell you the contrary. When they write 0.1111 they mean 1111/10000.

If you stop and take a breath, I am sure you will agree that most people do
not understand any distinction.

Marc Battyani

unread,
Feb 6, 2005, 4:15:23 PM2/6/05
to

"Christophe Turle" <ctu...@nospam.com> wrote

> > I didn't followed this thread so may be out of context but I would do
> > this:
> > (format nil "~d" (round 201.0053 0.000001))
> > =>"201005300"
> >
>
> with CLisp 2.33.1, it gives :
>
> CL-USER> (format nil "~d" (round 201.0053 0.000001))
> "201005296"
>
>
> I hope my version of clisp is buggy with additions of mine, else it proves
> that even for simple things like this, errors are easy with floats.

Have you looked at *read-default-float-format* (and set it to 'double-float)
as Peter suggested ?

Or else if your tables have 4 digits after the decimal point then round at
that value:

(format nil "~d" (* 100 (round 201.0053 0.0001)))
=>"201005300"

(format nil "~d" (* 100 (round 201.005296 0.0001)))
=>"201005300"

Marc


Christophe Turle

unread,
Feb 6, 2005, 4:36:04 PM2/6/05
to
"Coby Beck" <cb...@mercury.bc.ca> a écrit dans le message de news:
7JvNd.14580$tU6.4781@edtnps91...

>
> Hi, Christopher, sorry to be "ganging up" on you here

Don't be sorry. Each one expresses his point of view. No trouble with that
;)

> but you appear to be using mostly argument by consensus here so I will
> just add that I too, am human and do not agree that .1111 means 1111/10000
> by default.
>
>> Your community is not human community it is a subset of it.
>
>> want a proof ?
>
> This i would like to see!
> But an interesting experiment might be a multiple choice question you
> could give to different sets of people:

ok.

> What does .1111 mean?
>
> a) .1111d0
> b) 1111/10000
> c) 1.111x10e-4
> d) all of the above
>
> I'd wager that the vast majority of groups polled would select d or not
> understand the question.
> Of those who understood the notational differences you would get a split
> between d and "can't answer this trick question, sorry"

They will all understand the question. But the vast majority will not
understand a) and less c) but all will agree that b) is potentially true (if
not completly true).

So what should be the default interpretation ?

b) seems the reasonable choice.

An other thing : if one has to write on a paper the rational 1111/10 they
will write 111.1 and not 1111/10 (except when doing math). Did you ever see
this notation used for prices, temperature ?

Christophe Turle

unread,
Feb 6, 2005, 4:49:37 PM2/6/05
to
"Marc Battyani" <Marc.B...@fractalconcept.com> a écrit dans le message
de news: cu61d0$r...@library2.airnews.net...

>
> "Christophe Turle" <ctu...@nospam.com> wrote
>> > I didn't followed this thread so may be out of context but I would do
>> > this:
>> > (format nil "~d" (round 201.0053 0.000001))
>> > =>"201005300"
>> >
>>
>> with CLisp 2.33.1, it gives :
>>
>> CL-USER> (format nil "~d" (round 201.0053 0.000001))
>> "201005296"
>>
>>
>> I hope my version of clisp is buggy with additions of mine, else it
>> proves
>> that even for simple things like this, errors are easy with floats.
>
> Have you looked at *read-default-float-format* (and set it to
> 'double-float)
> as Peter suggested ?

Changing the float precision just push the general problem farther. One day,
one number out of float precision will come and errors will begin to appear
...

No escape with float. The solution is to hack the reader (using macro
characters as suggested) to capture rational values.

> Or else if your tables have 4 digits after the decimal point then round at
> that value:
>
> (format nil "~d" (* 100 (round 201.0053 0.0001)))
> =>"201005300"
>
> (format nil "~d" (* 100 (round 201.005296 0.0001)))
> =>"201005300"
>

You give me the staff to beat you ;)

I think that 201.005296 MHz has to be interpreted as 201005296 Hz not
201005300 Hz

Coby Beck

unread,
Feb 6, 2005, 5:24:25 PM2/6/05
to
"Christophe Turle" <ctu...@nospam.com> wrote in message
news:4206865c$0$1007$626a...@news.free.fr...

> "Coby Beck" <cb...@mercury.bc.ca> a écrit dans le message de news:
> dVuNd.14567$tU6.6609@edtnps91...
>> of the characters in its representation. There is no reason, absent that
>> context, to believe that the best interpretation of .123 is 123/100.
>
> Yes and No. When you don't specify context the default one apply so there
> is a context.

Sorry, there is no such thing as "default context" for any number. There is
only "context" which may or may not be known and it is always a dangerous
thing to assume something that is not known. This may well be a requirement
of an application, but should not be a feature of a programming language or
an implementation thereof. So what is left, if we can not assume a context?
Specify the behaviour. This specification will necessarily be arbitrary to
some degree, that can not be helped.

If you now approach the problem from this perspective, you may find your
judgements as to the relative merits of history, industry norms,
implementation details and user preferences (expectations?) somewhat
altered.

> Now, what is the default context when humans see ".12455". I argue that it
> means 12455/100000. I even argue that for the most part, programmers it
> means the same thing. And even for float intensive users, this means that
> when they see it on a price ticket ;)

So you assert, others seem to disagree. You must admit it is a subjective
assertion, absent some kind of very complex polling process at least.

>> Not only that, I completely reject the notion that a naive human who
>> types at a terminal ".123" most probably means 123/100.
>
> You reject evidence : ask your wife if she interprets 0.1 the same as
> 1/10. I bet the answer is yes.

I'll pretend I have a wife and she said yes. I say yes, too. Now I ask her
is .33 the same as 1/3. She again said yes. I said, "well, that depends."
Now I asked her does she want a computer programming language to interprete
.1111 as 1111/10000 or as some implementation dependant floating-point
aproximation of 1.111x10e-4. I said 1.111x10e-4 and she told me to leave
her alone.

But this is anecdotal, not useful evidence of anything.

>> I suggest that in ~99/100% of
>
> Do you mean 99% ??? i suspect a typo there which is important for the rest
> of the comprehension.

yes, sorry.

>> non-computer scientist cases, the naive user does not even know what they
>> really mean and in nearly as many, would not care. In computer
>> professional cases it may well be quite high as well. Even if not, it is
>> very probable that in 90% of cases it will not matter.
>>
>> As for the smaller number of times that it does matter, no amount of
>> machinary can remove the obligation from the programmer to use the
>> correct programming techniques nor from the user to understand the
>> context of the numbers they read.
>>
>> I am a bit mystified as to why the other side of this equation is being
>> ignored, that is the writing part of reading and writing data. If your
>> program produces 123/100 and you write it to a file as .123, then this is
>> where the bug is hatched.
>
> "0.123" is the more human common way to write 123/100. No bugs there.

You just ignored my point, btw. In the context of ANSI CL as it now is, if
you write a program that puts .123 in a file when the answer was 123/100 and
it is then read by another program as .123d0 you do so have a bug. My point
is that the bug is in the program that wrote the file.

BTW, .123 is also the common human way to write .1230000563372 or
.12299999999 and if I am writing a cheque then it would be .12

Is 123/1000 = 12300/100000? Does a human expect something different from
.123 and .12300? Not the naive human you want to satisfy, I daresay. My
pretend wife says the are the same. Lisp says there the same. A chemist
probably would not.

Computer languages are for computers and a small subset of humans who
program them, no one else.

Kent M Pitman

unread,
Feb 6, 2005, 5:28:26 PM2/6/05
to
Cameron MacKinnon <cmack...@clearspot.net> writes:

> Kent M Pitman wrote:
> > Floating point is very close to [being fundamentally embedded] in the
> > computer world, given that there is floating point hardware on nearly
> > every machine, and decades of history involving thousands, perhaps
> > even millions, of programmers who are familiar with the "meaning" of
> > 0.11111 in computerese.
>
> I suspect that of all the people who have ever written floating point
> code (and here I'll be generous and exclude mere spreadsheet users),
> fewer than half of them even realized that the representation was
> inexact, and perhaps one in fifty understood enough to be wary of the
> pitfalls.

Definitely. I have made this point many times. I myself use floating
point only for the most simple-minded of uses, and am frequently heard
to say (much to the consternation of my colleagues) that I "don't
understand" floating point. By which I usually mean "I understand
just enough about the odd-shaped space of points its baroque
representation designates to know I'm probably very bad at having any
intuitive understanding of its moment-to-moment variations in
precision as data changes from things that are more precisely
represented to things that are less precisely so". And since most
people don't seem to understand what I mean by that, I usually resort
to just saying I don't understand it at all, which seems to make them
think they understand better. Heh.

I have often also compared floats to LOOP in this regard. Deceptively
simple in how it draws you in, but you sometimes have to be an expert
in order to know for sure whether what seems to make sense in English
in fact means what it looks like it means. As such, it appeals to almost
exactly the segment of the user base for which it is not intended. I've
mellowed somewhat in my feelings about LOOP over the years, but not so
much in my feelings about floats...

> There was perhaps a time when the majority of users of general purpose
> FP hardware wanted inexact math without error bounds calculation by
> default -- i.e they were willing to live with the occasional need for
> numerical analysis and the odd model blowing up because they couldn't
> afford the cycles or the gates to compute cumulative errors along with
> their shady numbers. That time is long past, I think.

A reasonable point is made here, so let me back up slightly to at least
this extent:

I once made a similar case about how the time had passed for Lisp to
start up in base 8, and how "modern users" all expected "base 10". At
this point, I won't try to embarrass anyone you may revere by giving
the long list of names of people who pooh-poohed the idea as
ridiculous and who argued seriously that base 8 was better and users
just didn't know what was good for them. I was, for a while, in a
minority among the designers, who lagged the users in the obvious
truth.

I won't claim that situations like you describe don't happen.

But the question is, as much, whose responsibility it is to be taking
the step forward into the brave new word you describe.

I could equally well make the case that rather than give us 6GHz
processor chips for Christmas, we might appreciate 3GHz chips with a
hardware BCD feature instead. And then ALL languages could give some
thought to whether to switch over.

I don't think the Lisp community's user base is strong enough to lead
the pack into an enlightened future that forces hardware support, and
absent hardware support, I think we'll just be laughed at as a toy.
We HAVE support for rationals, which is better than most languages.
But I don't see a pressing need to abandon what little syntax
compatibility we have with other languages ... we went to a lot of
trouble to make the float syntax, the FORMAT ops, etc. be as
compatible as possible with IEEE, with the Fortran language, etc.

If it's time for the change you're asking for, it's up to IEEE to do
it. I won't disagree with a claim that with processors getting faster
and faster, almost to the point of uselessness, it's time for us to
put in some onboard support for things the common person has needed
for ages. I just think, if anything, that fixing it at the
superficial level and not at the underlying level, is reducing
pressure on the proper authorities to fix it right.

I have made a similar process argument, by the way, about how
recycling of waste materials should work in my town. Some of my
friends are willing to drive to the dump, but I always tell them they
shouldn't. They should hold out for door-to-door service. They
dillute and use up their precious interest in this topic by the time
they spend driving across town to put in their petty amounts of
trash. And they consider the problem fixed for themselves, and sit
waiting for "the masses" to get with it and do the same. But the
masses are lazy, and no such end comes. If they instead they insisted
on being lazy and just didn't consider the problem solved until
EVERYONE had recycling pickup from their door, they (a) wouldn't have
to drive their trash to the dump and (b) wouldn't use up the time they
have to devote on the matter in solving the problem imperfectly. By
being lazy, they force a solution that even suits lazy people. If
they're bugged, let them use that time they had to drive across town
being on the phone to a Congressperson lobbying for change. Because a
solution to THAT problem will serve everyone, even the lazy people,
and will bring orders of magnitude larger returns.

So here I sit, following my carefully crafted "lazy is better"(TM)
strategy to get IEEE to fix the problem. The last thing we need is a
place for people who are annoyed to take happy refuge and stop
bothering the chipmakers and standardsmakers who could make a REAL
difference.... ;)

Kent M Pitman

unread,
Feb 6, 2005, 5:29:52 PM2/6/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> "0.123" is the more human common way to write 123/100. No bugs there.

Geez, and here I thought 1.23 was the more human, common way to write 123/100. ;)

David Steuber

unread,
Feb 6, 2005, 5:30:27 PM2/6/05
to
"Coby Beck" <cb...@mercury.bc.ca> writes:

> I am a bit mystified as to why the other side of this equation is being
> ignored, that is the writing part of reading and writing data. If your
> program produces 123/100 and you write it to a file as .123, then this is
> where the bug is hatched.

Clearly this is a nasty bug.

--
An ideal world is left as an excercise to the reader.
--- Paul Graham, On Lisp 8.1

David Steuber

unread,
Feb 6, 2005, 5:36:28 PM2/6/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> 'human context' means humans in general. How many % of documents written by
> humans which include 0.1111111 to be interpreted as a float ?

As a rough estimate, and WAG, I would say 100%.

> And even within programmers, what is the % of them that really need the
> knowledge of float if they were given the rational choice ? the vast
> majority of Applications don't need float to be written. It is just usefull
> at the optimization stage.

Do you have data for this? Every time I use floats of whatever
precision it is because I really do need them.

Coby Beck

unread,
Feb 6, 2005, 5:43:44 PM2/6/05
to

"Cameron MacKinnon" <cmack...@clearspot.net> wrote in message
news:X82dna2XWdg...@golden.net...

>> What you ARE obliged to do is to write code that is not there by
>> default. Lisp enables you to do many things, but one of the things
>> you are not enabled to do is to wish for things and have them come
>> into existence without any work.
>
> True... That's what c.l.l is for! The original poster got helpful code
> and suggestions, but also, disturbingly, comments to the effect that
> yes, Lisp is a programmable programming language, but you shouldn't
> program it THAT way.

I don't think that is a fair comment. What you got was people saying how
the problem could be soved and disagreeing with the suggestion that there is
something broken in the design of the language.

Coby Beck

unread,
Feb 6, 2005, 5:49:09 PM2/6/05
to
"Christophe Turle" <ctu...@nospam.com> wrote in message
news:420690f6$0$1211$626a...@news.free.fr...

> No escape with float. The solution is to hack the reader (using macro
> characters as suggested) to capture rational values.

No comment on the reading part, but it seems to me that a more apropriate
abstraction would be to capture Hz, best represented as an integer (if that
is precise enough?) and then format it as you chose.

Marc Battyani

unread,
Feb 6, 2005, 5:52:20 PM2/6/05
to

"Christophe Turle" <ctu...@nospam.com> wrote:

> I think that 201.005296 MHz has to be interpreted as 201005296 Hz not
> 201005300 Hz

No, you are talking radio channels and telecom crystals are typically at 10
ppm. That's 10e-5, so 5 digits are enough. So with a double-float you are
safe. ;-)

Marc
(I just finished to design a 2.4GHz radio system)


David Steuber

unread,
Feb 6, 2005, 5:58:41 PM2/6/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> "Christophe Rhodes" <cs...@cam.ac.uk> a écrit dans le message de news:
> sqlla1i...@cam.ac.uk...


>
> > "if I write 0.1111, I imply something different from if I write
> > 1111/10000"
>
> I bet that the vast majority of humans don't agree with your sentence and
> will tell you the contrary. When they write 0.1111 they mean 1111/10000.

I'll provide a data point. I agree with Christophe. The following
REPL interaction is what I would expect from a machine:

CL-USER> (* 1.0d0 1/9)
0.1111111111111111D0
CL-USER> (* 1.0 1/9)
0.11111111
CL-USER> 0.1111
0.1111
CL-USER> (* 9 0.1111)
0.99990004
CL-USER> (* 9 1/9)
1
CL-USER> (* 9.0d0 1/9)
1.0D0
CL-USER> (* 9.0 1/9)
1.0
CL-USER> (* 9.0d0 0.1111d0)
0.9999D0

OpenMCL 0.14.2-p1 on Darwin.

Christophe Turle

unread,
Feb 6, 2005, 6:11:46 PM2/6/05
to
"Kent M Pitman" <pit...@nhplace.com> a écrit dans le message de news:
u8y618...@nhplace.com...


Since the number 0.123 (or 123/1000) was in my head at the time i have wrote
this, i'm more and more inclined to think that 0.123 is really a better
notation for rationals ;-)

Coby Beck

unread,
Feb 6, 2005, 6:21:20 PM2/6/05
to
"Christophe Turle" <ctu...@nospam.com> wrote in message
news:42068dc9$0$1007$626a...@news.free.fr...

> "Coby Beck" <cb...@mercury.bc.ca> a écrit dans le message de news:
> 7JvNd.14580$tU6.4781@edtnps91...
>> What does .1111 mean?
>>
>> a) .1111d0
>> b) 1111/10000
>> c) 1.111x10e-4
>> d) all of the above
>>
>> I'd wager that the vast majority of groups polled would select d or not
>> understand the question.
>> Of those who understood the notational differences you would get a split
>> between d and "can't answer this trick question, sorry"
>
> They will all understand the question. But the vast majority will not
> understand a) and less c) but all will agree that b) is potentially true
> (if not completly true).
>
> So what should be the default interpretation ?
>
> b) seems the reasonable choice.

Well, you would leave the decision to people who do not understand the
question. This seems doomed to fail, regardless of the consensus you might
achieve.

William Bland

unread,
Feb 6, 2005, 8:03:31 PM2/6/05
to
On Sun, 06 Feb 2005 13:12:31 +0100, Christophe Turle wrote:
>
> Seeing digits as macro characters ! Yes, it's a very good idea and it is CL
> standard, cool !
>
> thanks for the hack ;)
>

Glad you liked it. Here's another one I just wrote that seems relevant to
this thread (scroll to the end for an example of its use):

(defvar *digits* '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\.))

(defclass number-with-error-bar ()
((number
:initarg :number
:initform (error "Must supply a number."))
(error-bar
:initarg :error-bar
:initform 0)))

(defmethod print-object ((x number-with-error-bar) stream)
(format stream "~A+/-~A" (slot-value x 'number) (slot-value x 'error-bar)))

(defun plus (&rest numbers)
(let ((result 0)
(result-error 0))
(dolist (n numbers)
(typecase n
(number
(incf result n))
(number-with-error-bar
(incf result (slot-value n 'number))
(incf result-error (slot-value n 'error-bar)))
(t
(error "Cannot add ~S" n))))
(if (= result-error 0)
result
(make-instance 'number-with-error-bar
:number result :error-bar result-error))))

(defun read-number-with-error-bar (stream char)
"read all numbers as numbers with error bars"
(let ((this-char nil)
(result (position char *digits*))
(n 0)
(position-of-dot nil))
(loop while (member (peek-char nil stream) *digits*) do
(setf this-char (read-char stream))
(if (eql this-char #\.)
(setf position-of-dot n)
(setf result (+ (* 10 result) (position this-char *digits*))))
(incf n))
(if position-of-dot
(make-instance 'number-with-error-bar
:number (/ result (expt 10 (- n position-of-dot 1)) 1.0)
:error-bar (/ 0.5 (expt 10 (- n position-of-dot 1))))
result)))

(mapcar (lambda (c)
(set-macro-character c #'read-number-with-error-bar))
(remove #\. *digits*))

(set-macro-character #\+
(lambda (stream char)
(declare (ignore char))
(let ((result (make-array '(1)
:element-type 'base-char
:fill-pointer t :adjustable t
:initial-contents '(#\+))))
(loop until (member (peek-char nil stream)
'(#\( #\) #\Space
#\Newline #\Tab)) do
(vector-push-extend (read-char stream) result))
(if (equal result "+")
'plus
(intern result)))))

;; end of file

CL-USER> 1
1
CL-USER> 1.0
1.0+/-0.05
CL-USER> 1.00
1.0+/-0.005
CL-USER> (+ 1 2.0 3.00 4.000)
10.0+/-0.0555
CL-USER> (reduce #'+ (make-list 100 :initial-element 1.0))
100.0+/-5.000001
CL-USER> '+
PLUS
CL-USER> '++
++
CL-USER> '+a-symbol+
|+a-symbol+|


Some people say it's a good thing for a language to be "objects all the
way down". Lisp is much more than that - it's programmable all the way
down.

Cheers,
Bill.

Gareth McCaughan

unread,
Feb 6, 2005, 8:16:19 PM2/6/05
to
David Steuber wrote:

> "Christophe Turle" <ctu...@nospam.com> writes:
>
>> "Christophe Rhodes" <cs...@cam.ac.uk> a écrit dans le message de news:
>> sqlla1i...@cam.ac.uk...

...


> I'll provide a data point. I agree with Christophe.

In most contexts, that would be sufficient to indicate which
side you're on. However, the two disagreeing posters quoted
above are Christophe Turle and Christophe Rhodes. :-)

(Yes, it *was* clear from what you then went on to say...)

--
Gareth McCaughan
.sig under construc

Barry Margolin

unread,
Feb 6, 2005, 9:10:15 PM2/6/05
to
In article <420670c4$0$958$626a...@news.free.fr>,
"Christophe Turle" <ctu...@nospam.com> wrote:

> It works with double float. But the point is : why MUST i care about float
> type EVEN if i'm not concerned with optimization ???

Because you're not the only programmer, and other programmers have
concerns different from yours. The language has to cater to a wide
variety of needs. For many of them, floating point is the proper tool,
and CL provides it, just like most other languages.

If you don't need floating point, don't use it. But it seems really
conceited of you to expect that the language should be designed to
facilitate your specific application rather than others.

--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***

Barry Margolin

unread,
Feb 6, 2005, 9:15:34 PM2/6/05
to
In article <4206865c$0$1007$626a...@news.free.fr>,
"Christophe Turle" <ctu...@nospam.com> wrote:

> "0.123" is the more human common way to write 123/100. No bugs there.

Except for the factor-of-10 error. :)

Barry Margolin

unread,
Feb 6, 2005, 9:23:24 PM2/6/05
to
In article <42064cff$0$951$626a...@news.free.fr>,
"Christophe Turle" <ctu...@nospam.com> wrote:

> I bet that the vast majority of humans don't agree with your sentence and
> will tell you the contrary. When they write 0.1111 they mean 1111/10000.

I think this argument is pretty silly. What they intend probably
depends on context.

If you say that the normal human body temperature is 98.6 degrees, you
don't really mean (if you know what you're talking about) it's exactly
98.6000000 -- it's *about* 98.6. So a numerical system that deals with
approximations will generally work fine.

But if you're dealing with money, and you pay a bill for $98.60, you
would be very surprised if $98.61 were taken out of your checking
account.

Floating point works OK in scientific applications, where the readings
that come from measurement devices are inherently noisy. Although what
you really might want is an arithmetic system that automatically
incorporates margins of error, e.g. 100.1+/-.05 + 51.3+/-.05 =
151.4+/-.1.

David Steuber

unread,
Feb 6, 2005, 10:07:54 PM2/6/05
to

Christophe Turle wrote:
> "Coby Beck" <cb...@mercury.bc.ca> a écrit dans le message de news:
> dVuNd.14567$tU6.6609@edtnps91...
> >
> > I am a bit mystified as to why the other side of this equation is
being
> > ignored, that is the writing part of reading and writing data. If
your
> > program produces 123/100 and you write it to a file as .123, then
this is
> > where the bug is hatched.
>
> "0.123" is the more human common way to write 123/100. No bugs there.

Are you absolutely sure about that? Read it again :-)

David Steuber

unread,
Feb 6, 2005, 10:31:33 PM2/6/05
to

Coby Beck wrote:
>
> What does .1111 mean?
>
> a) .1111d0
> b) 1111/10000
> c) 1.111x10e-4
> d) all of the above

Certainly not C, although I might buy 1.111x10e-1 (or 1.111e-1) and
therefor also not D.

Being pedantic, I would also discount A because a single float is not
really the same as a double float. B looses out not just for reasons
of type, but also lack of equality:

CL-USER> (equal 0.1111 1111/10000)
NIL

Then again, A suffers the same problem:

CL-USER> (equal 0.1111 0.1111d0)
NIL
CL-USER> (= 0.1111 0.1111d0)
NIL

(both ways just to be sure)

> I'd wager that the vast majority of groups polled would select d or
not
> understand the question. Of those who understood the notational
differences
> you would get a split between d and "can't answer this trick
question,
> sorry"

Trick question is probably the right answer.

If I obtained 0.1111 as a measurement, then the number is most
definitely aproximate. That is the typical use of floating point. If
that number was intended to be an exact fraction of a dollar, then you
are already likely to be in trouble. This is not the way to count
money!

At least 1111/10000 is unambiguously exact.

Just for grins, I tried some stuff in Python. For all the hype, I
would say that this language has its issues as well, not the least of
which is the apparant inability to express the size of the float (it
appears to take doubles by default):

$ python
Python 2.3 (#1, Sep 13 2003, 00:49:11)
[GCC 3.3 20030304 (Apple Computer, Inc. build 1495)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 0.1111 * 9
0.99990000000000001
>>> 1/2
0

Gee, not only no rationals, but it divides as C does!

Wade Humeniuk

unread,
Feb 6, 2005, 10:39:18 PM2/6/05
to
Coby Beck wrote:

>
> This i would like to see!
> But an interesting experiment might be a multiple choice question you could
> give to different sets of people:
>
> What does .1111 mean?
>
> a) .1111d0
> b) 1111/10000
> c) 1.111x10e-4
> d) all of the above
>
>

Actually I see that it is meant as .1111... (repeating
decimal)

which is 1/9

Wade

David Steuber

unread,
Feb 6, 2005, 10:49:37 PM2/6/05
to

David Steuber wrote:
> "Christophe Turle" <ctu...@nospam.com> writes:
>
> > "Christophe Rhodes" <cs...@cam.ac.uk> a écrit dans le message de
news:
> > sqlla1i...@cam.ac.uk...
> >
> > I bet that the vast majority of humans don't agree with your
sentence and
> > will tell you the contrary. When they write 0.1111 they mean
1111/10000.
>
> I'll provide a data point. I agree with Christophe.

Ack! I ment C. Rhodes.

Coby Beck

unread,
Feb 6, 2005, 11:23:39 PM2/6/05
to

"Wade Humeniuk" <whumeniu+...@telus.net> wrote in message
news:GpBNd.11618$gA4.9436@edtnps89...

Darn! I knew there were more choices I was going to put in before I got to
writing it. And with David Steuber's correction, the question should read:

What does .1111 mean?

a) .1111d0
b) 1111/10000
c) 1.111x10e-1
d) 1/9
e) all of the above

But you get the point...

Christopher C. Stacy

unread,
Feb 7, 2005, 5:49:43 AM2/7/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> "Christopher C. Stacy" <cst...@news.dtpq.com> a écrit dans le message de
> news: uhdkps...@news.dtpq.com...
> > Can you show us some code in the other programming language(s)
> > to which you are referring in which numbers with a decimal point
> > do not indicate a floating point number?
>
> Perhaps some exists, but i don't know about. But it's not a sufficient
> reason why it should be like this. Reasons must be objective ones not
> 'follow others' ones.
>
>
> > By the way, what TV channel frequencies are you being handed
> > that are not conveniently represented by floating point?
>
> (rationalize 201.0053) ; in MHz
> => 37990/189


>
> It works with double float. But the point is : why MUST i care about float
> type EVEN if i'm not concerned with optimization ???

Because floating point is how all computer programming languages,
including Lisp, do arithmetic when they see a number with a decimal point.

Lisp does offer an unusual alternative not available in most other
languages, which is rational numbers. But to use that facility,
you have to write the number in a different way so that Lisp will
know that you don't want to do the normal thing.

Christophe Rhodes

unread,
Feb 7, 2005, 6:11:09 AM2/7/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> You give me the staff to beat you ;)
>
> I think that 201.005296 MHz has to be interpreted as 201005296 Hz not
> 201005300 Hz

As well as Marc's point that typical crystal frequency tolerance is
about 10 parts per million, don't forget that to send a useful signal
your signal with base frequency of 201.005296 MHz needs to be
modulated, which implies that your channel will have a certain
bandwidth.

Let's say that you're interested in transmitting speech-quality data,
so a modulating frequency of about 22kHz is adequate -- if you want
music or video, obviously you'll need a higher modulating frequency,
and probably your transmitter won't lie in the MHz range. Then your
band actually lies between 200.083296 MHz and 201.027296 MHz.

Given this, do you really think it's sensible to require your
transmitting frequency to be printed and treated as exactly 201.005296
MHz? Or would 201.0 perhaps be a better representation? (If you're
sending less dense information than speech, then you might be
interested in one or two more significant figures -- but not very many
more, because of the limit imposed by your transmitter.)

Christophe

Christopher C. Stacy

unread,
Feb 7, 2005, 7:27:43 AM2/7/05
to
"Christophe Turle" <ctu...@nospam.com> writes:
> Even for programmers this is bad choice.

In the realm of general purpose programming with fractions,
there are three choices: floating point, fixed point, and rationals.
Lisp gives you the two most useful: floating point is for doing fast
calculations, and rationals are for doing exact computations.
Lisp doesn't offer the one that's limited, inexact, and slow.

Most other languages in use today have chosen to only provide
floating point. They do not have a "default", since there is
no choice. Lisp has a default, and it uses the syntax that is
most compatible with those other languages

Whether that's a "bad choice" depends on what kind of programs
you're writing and how important the optimizations for speed

> Don't misunderstand me : float are useful but just for an optimization
> purpose. So with app using lots of number computation, i'm sure that
> programmers have to know how to use floats. But for the rest, and they are
> the large majority of App, you don't need them, if an other choice were

I don't know where you are coming up with the "majority" opinion.
Apparently, though, you have been out-voted: floating point has
been placed into all the hardware, and support for fixed-point
(such as string-oriented numerics and BCD, which used to be fairly
popular in hardware) have been removed.

The languages that offer fixed-point require you to annotate your
variables with declarations using words like :"CURRENCY" or "fixed
decimal" or "USAGE COMP-3" or "is delta 0.01 digits 5 range 0.0..99.88".
You can do the equivalent thing in Lisp by writing a function
that takes your input string and converts it into the exact
representation of a rational number.

It would be possible to change the Lisp language to support the
default input numeric format that you want, but that's not happening.
But you have even been shown several ways to kludge it up in the
existing language, a feat which is inconceivable in the other
programming languages.

Now go implement your solution, using either the annotation approach
used in other languages, or using the hack. Trying to convince a
community of people who are invested in a backwards-compatability,
standards-based, stable programming language that they should change
how this default works is a waste of time, especially since nobody
seems to agree with you about its desirability.

There no reason for Lisp programmers to be interested in writing
literal decimal-point constants representing fixed-point numbers
in their code. They would use rational syntax, instead. And when
doing string processing of someone else's data, such as currency,
they just write whatever parser (and if necessary, new data types
and methods) that are needed to get the desired numerical results.

If Lisp standards or implementations were going to change something
related to this at all, it would be to better support very large
arrays and block-compilation and memory mapping of unboxed floats.

Alan Crowe

unread,
Feb 7, 2005, 8:53:17 AM2/7/05
to
Christophe Turle answered mmcconnell:
>> In your application, do you know for sure that the decimals are exact?
>> That is, if your file has 1.3333, are you sure it's 13333/10000 and not
>> 4/3 ?
>
>yes i am.

William Bland has already given the best answer with his
read macros.

Nevertheless, this hack might not be too crude.
If you know that the decimals in your input are restricted
to being a modest number of digits then RATIONAL and
RATIONALIZE both come close to solving the problem.

RATIONAL fails because the denominator is always a power of
2.

RATIONALIZE fails because the denominator is unconstrained.

Writing ones own version that constrains the denominator to
be a power of ten will serve for numbers of modest
precision.

(defun close-to-integer (number tolerance-factor)
(multiple-value-bind (integer discrepancy)
(round number)
(if (< (abs discrepancy)
(* tolerance-factor single-float-epsilon))
integer
nil)))

(defun rat-ten (float)
(do ((number float (* 10 number))
(tolerance 2 (* 10 tolerance))
(numerator 1 (* 10 numerator)))
((close-to-integer number tolerance) (/ (round number)
numerator))))

CL-USER(77): (- 1.001 1) => 0.0010000467
CL-USER(78): (- (rat-ten 1.001) 1) => 1/1000

This will serve for perhaps 14 digits if you set
*read-default-float-format* to double-float and use the
double-float-epsilon

(- 1.00000000000001 1) => 9.992007221626409e-15
(- (rat-ten 1.00000000000001) 1) => 1/100000000000000

Alan Crowe
Edinburgh
Scotland

mmcconn...@yahoo.com

unread,
Feb 7, 2005, 11:14:46 AM2/7/05
to
I stand corrected. 102005096/1000000 is wrong, because you want
1020051/10000

The issue has nothing to do with Lisp. You'd encounter the same issue
in C, Basic, or any language that uses floating-point arithmetic. The
definition of floating-point is to use the number in the computer's
binary representation that is closest to the real number whose name
you've typed. When you type 102.0051, the computer willfully
misunderstands you to mean some rational number with a power of 2.

If you want a power of 10 rather than a power of 2, then you're doing
"input formatting", not floating-point arithmetic. Nothing wrong with
"input formatting", we just have to define our terms.

I would write an input formatter, using string functions like "number
of characters after the decimal point". Whether to do is as a
function, macro, or reader macro is something I care about less.

Wade Humeniuk

unread,
Feb 7, 2005, 11:26:09 AM2/7/05
to
Coby Beck wrote:

> Darn! I knew there were more choices I was going to put in before I got to
> writing it. And with David Steuber's correction, the question should read:
>
> What does .1111 mean?
>
> a) .1111d0
> b) 1111/10000
> c) 1.111x10e-1
> d) 1/9
> e) all of the above
>
> But you get the point...
>

Yup, I get the point. What the person MEANT is dependent on the context
in which it was expressed. .1111 could mean in a computer programing
context a binary fraction. In business it could mean 11.11%, compounded
anually. I cannot think of a situation of where .1111 means 1111/10000
unless it is an artificial human number like an interest rate or
a quick approximation for 1/9 when using a hand held calculator.
Computers make honest men of us all by forcing us to say
exactly what we mean.

A number like that might show up in physics or chemistry, but there it
means .1111+/-.00005 To leave off the uncertainty there is to
entertain disaster.

Wade

Kent M Pitman

unread,
Feb 7, 2005, 12:25:52 PM2/7/05
to
cst...@news.dtpq.com (Christopher C. Stacy) writes:

> > It works with double float. But the point is : why MUST i care about float
> > type EVEN if i'm not concerned with optimization ???
>
> Because floating point is how all computer programming languages,
> including Lisp, do arithmetic when they see a number with a decimal point.

Right. And, more to the point, it's how computers do it.

One of the reasons we call them "computer programming languages" is that it's
the language for programming the
<quotemarks device="fingers" style="Austin Powers">computer</quotemarks>.

And while it is certainly true that hardware can be emulated by program,
programming is a task that we often leave to the user. The part the user can't
program is access to the native hardware, and that's what we provide through
floats. If memory serves, that's precisely what we meant where we used the
phrase "codify existing practice" in the original X3J13 charter document.
See for reference: http://www.nhplace.com/kent/CL/x3j13-86-020.html

Also lost in this conversation:

The job of a standard is not to create practice, but to document it.
If the original complaint were that all programmers everywhere ignore
floating point and writes BCD subroutines to achieve correctness, that
would make a more compelling case as a linguistic criticism.

If the original complaint were even that all vendors offer BCD
substrates and that the language makes it hard to expose these much
more common substrates because it provides a substrate that everyone
wishes would go away, that would als omake a more compelling
criticism.

A footnote:

One of the reasons that standards have, to my mind, somewhat fallen
away in the modern world (left as "history" and no longer the central
focus of all computational activity) is that in the modern pluralistic
state, the needs of the many are, well, many. People no longer want
to do the global synchronization step of beating everyone else into
the dull stupor that so roughly implements to global agreement.
Rather, they want to be personally empowered to make choices good for
themselves notwithstanding the desires of other people to make other
choices, good or bad.

As such, one of the only notions of "good" that I recognize any more is
"supports individual choice". Since we already support complete control
of redefining the reader, I think we can tick off the "supports choice"
box there. Since we support the most common kind of math (the kind everyone
seems to want on-chip), and since we provide substantial support for
alternatives besides, not just in terms of rationals but also in terms of
a package system, generic functions, and other tools for permitting language
extension or customization, I think we can tick that off, too.

So it's not obvious what's being discussed here other than the old theory
of beating people into an unwanted stupor. So unless there is some
surprisingly new material on this thread, I think I've said all I have to
say.

Cameron MacKinnon

unread,
Feb 7, 2005, 12:27:57 PM2/7/05
to
Wade Humeniuk wrote:
> Coby Beck wrote:
>
>>
>> This i would like to see!
>> But an interesting experiment might be a multiple choice question you
>> could give to different sets of people:
>>
>> What does .1111 mean?
>>
>> a) .1111d0

This is nonsensical except to some computer programmers. Among the
broader numerate population, the letter d never appears in the middle of
a number.

>> b) 1111/10000

Everyone is taught in primary school that 1111/10000 and 0.1111 are the
same number. Lispers associate fractions with exactitude, but this is
certainly not the case among the broader public.

>> c) 1.111x10e-4

...and they learn that scientific notation is used as a terse notation
for numbers whose significant digits lie far from the decimal point. The
notation implies a physical constant or measurement, which further
implies limited accuracy and finite error.

>> d) all of the above

Programmers tend to make artificial distinctions between the above
number formats, because our languages overload the notation to choose
between various internal representations, something non programmers
don't know about.

> Actually I see that it is meant as .1111... (repeating
> decimal)
>
> which is 1/9

This is reasonable, but I would have lost marks in elementary school if
I'd said that 0.1111 and 0.1111... were equivalent. Further, and this is
key, I don't think casual users and the nearly innumerate would be
surprised if they punched in 0.1111 and the computer used that number
exactly (instead of guessing that 1/9 was desired) for their
calculation. Even if they WERE surprised, there's a logical and
intuitive way to hint to the machine that more digits are required --
just add more digits.

Of course, I don't think there's anything stopping a conforming Lisp
from storing 0.1111 as 3^-2 so people writing portable code shouldn't
depend on it being otherwise.


The quiz writer didn't offer the choice of 7455795/67108864. I wonder
why not?

The whole quiz is bogus. It is attempting to enlighten us on the
question "what should a computer assume about a number, absent context?"
A better question to investigate might be "what can a computer discover
about a number, given context?" Might we not use hints such as whether
the number is involved in indexing, whether it is converted to base 10
(i.e. printed) and with what precision?

Thomas A. Russ

unread,
Feb 7, 2005, 1:27:44 PM2/7/05
to
"Christophe Turle" <ctu...@nospam.com> writes:
> the problem is that i want to print the value as a HZ value so :
>
> (my-print-fct (read-from-string "201.0053"))
> => "201005300"
>
> without float burden it should have simply been :
>
> (defun my-print-fct ( in-Mhz )
> (format nil "~d" (* 1000000 in-Mhz)) )
>
> i'm waiting for your solution.

This is a different problem.
Look at the reference to the MEASURES package.

If you want an updated version of that that I've worked on a bit, it is
also packaged up with our Loom package (but you can just extract the
measures part of it). IIRC there is even an option to treat all values
as rational numbers. If not, it could easily be added to the reader...

Original Measures: http://tinyurl.com/5lppy
In Loom: http://www.isi.edu/isd/LOOM/how-to-get.html


--
Thomas A. Russ, USC/Information Sciences Institute

Thomas A. Russ

unread,
Feb 7, 2005, 1:16:45 PM2/7/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> I agree. And the context for Lisp should be compatible with human context.
> default float interpretation is not compatible with human reading. That's my
> point.

I disagree. The context for Lisp should be compatible with the
programming language context. It is, after all, a programming language
and it is more useful for it to conform to that environment.

> But as i said before, 0.1111 shouldn't be read as a
> float in Lisp. It is bad design choice.

Opinions can reasonably differ on this. In any case, the same design
choice has been made in just about every other programming language. At
least if it is "bad", it has lots of company. But that just reinforces
my argument above, that the behavior is what most people would expect
when approaching Lisp as a programming language.

But, this is likely to degenerate into a religious argument, so I
suppose we will just have to disagree on this evaluation.

Thomas A. Russ

unread,
Feb 7, 2005, 1:11:17 PM2/7/05
to
Kent M Pitman <pit...@nhplace.com> writes:

>
> "Christophe Turle" <ctu...@nospam.com> writes:
>
> > I can't change inputs. I have the string "(x 123.2569 y 1256.3588)" input
> > for example. So i can't introduce reader macros :(
>
> No, that's not so. That is, the assertion in your first sentence is not,
> as you seem to suggest, the result of some logical implication from the
> premise in the second sentence to an unavoidable conclusion in the third
> sentence.
>
> For example, you could make #\0, #\1, #\2, etc. be readmacros that
> could then read the rest of the number in whatever format they liked.

Actually, if one wants an example of something like this, the MEASURES
package from Roman Cunis does exactly this sort of thing in order to be
able to read items like 15m/s as a dimensioned number.

Here is a link to the CMU repository with that code:

http://tinyurl.com/5lppy

It would give you a start on writing a reader macro such as Kent suggests.

Thomas A. Russ

unread,
Feb 7, 2005, 1:23:17 PM2/7/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> 'human context' means humans in general. How many % of documents written by
> humans which include 0.1111111 to be interpreted as a float ?

How many % of documents written by humans are compilable by any
compiler?

How many % of programs written by humans interpret 0.1111111 as a float?

As Kent so eloquently pointed out, you should not be using the Lisp
reader to read non-lisp input. As much as this pains me to admit this,
I don't think you would have run into the same problem doing this in C
instead. That is because in C you would have to write your own parser
from scratch and could thus have placed any interpretation you wanted on
the input string. Just because Lisp makes reading input and parsing it
easier just makes it easier to misapply its tools.

In the time it takes to respond to all these messages, I bet you could
even write (or adapt from other sources) the reader macros you would
need to have the effects you desire.

Thomas A. Russ

unread,
Feb 7, 2005, 12:58:43 PM2/7/05
to
"Christophe Turle" <ctu...@nospam.com> writes:

> "Barry Margolin" <bar...@alum.mit.edu> a écrit dans le message de news:
>
> > Sure, we could have made .1111 read as a rational, and require you to
> > write something like .1111e0 to get a float, but why should we have? We
> > provided another syntax for rationals that didn't conflict with existing
> > practice -- if you want a rational, type 1111/10000.
>
> Because these practices are bad. And i don't want to write 1111/10000
> instead of .1111, it is not human conventional. It is just implementation
> details.

These practices are not "bad". They just happen to be inconvenient for
the particular problem you are trying to solve. But instead you are
advocating a system where the inconvenience would impact most other users
of the input system who want a convenient way of getting floating point
numbers.

There are very good engineering and compatibility with programming
language conventions reaons to have floating point numbers entered the
way they are.

Now, given the perennial confusion that floating point numbers seem to
generate, particularly with some new programmers, I actually think that
programming language should have a reasonably convenient way to enter
decimal (rather than binary) floating point numbers and support
arithmetic on them. Java has something in this direction (at least with
the support classes) but it isn't intergrated as well as the other
numeric types and the input formalism is not nearly as convenient.

It's actually too bad that the letter "d" is already taken for double
float, since it would have been a nice suffix to use for decimal
floats. Actually, an extension to lisp to implement decimal floats
might be a nice direction for language evolution.

And it would also allow Christophe to solve his problem by binding
*READ-DEFAULT-FLOAT-FORMAT* to this new decimal float type.

Cameron MacKinnon

unread,
Feb 7, 2005, 1:51:17 PM2/7/05
to
Barry Margolin wrote:
> In article <420600fd$0$956$626a...@news.free.fr>, "Christophe Turle"
> <ctu...@nospam.com> wrote:
>
>
>> Yes, i know it's not lisp code. And this is in fact my problem, why
>> IN lisp, .1111 is read as a float ? yes, the spec is the spec. But
>> for this point, imho the spec is not good.
>
>
> Why shouldn't it read it as a float? That's the way many dialects of
> Lisp have been reading and writing floats for decades, and Common
> Lisp was designed to be compatible with preceding dialects like
> Maclisp where feasible.

There's a lot to be said for backward compatibility, but do you expect
numeric formats to be frozen in time forever? We've moved from ASCII to
Unicode, from 16 bit to 64 bit integers, from plain text to complicated
markup languages (sigh) and from kilobytes to gigabytes of storage.

> It's also consistent with most other programming languages -- numbers
> with embedded decimal points are floating point.

True. So, just like other language fora, c.l.l has a trickling stream of
newbies who need to be told about floating point. And each one of those
earnest bug reporters probably represents ten programmers who have
noticed that their floats add a bit strangely but didn't investigate,
and a hundred programmers who didn't even notice.

You can claim that computers currently don't add like humans do and that
it is all the fault of poor education when programmers don't realize
this and write buggy software that blows up, sometimes literally. But I
think that if you're going to appropriate the symbols of the broader
culture (working in base 10, using conventional + - = notation), you've
a duty to make those symbols represent in the computer what they
represent in the minds of everyday people. Changing the definitions
slightly to save a few bits was an amazing hack back when RAM was
measured in bits and all of the users were pipe stress freaks and
crystallography weenies. Since then, the floating point impedance
mismatch between people and computers has been responsible for a lot of
pain.

Users of floating point enjoyed a ten year free ride from Intel et al,
constantly speeding up IEEE floats to benefit the 3D visualization
(gamer) crowd. Those people have now left the building, and are using
their own specialized 3D graphics silicon. Incidentally, IEEE is
updating 754 and merging in IEEE-854.

Much of my enthusiasm for Lisp is because it eliminates entire classes
of bugs which are endemic in virtually all software written in more
popular languages. As well, Lisp's wonderful malleability means that
those who need different semantics (such as our OP) can easily adapt it
to their needs.

But in the area of floating point, I would argue that Lisp is just as
broken as most other languages. For the average computer programmer,
floating point is an accident waiting to happen, not the ideal default.
Nor can it be said that Common Lisp is the best at supporting this
format, which admittedly has its uses. Where's directed rounding mode
support, or control over exception handling?

Kent M Pitman

unread,
Feb 7, 2005, 2:10:08 PM2/7/05
to
Cameron MacKinnon <cmack...@clearspot.net> writes:

> Much of my enthusiasm for Lisp is because it eliminates entire classes
> of bugs which are endemic in virtually all software written in more
> popular languages. As well, Lisp's wonderful malleability means that
> those who need different semantics (such as our OP) can easily adapt it
> to their needs.
>
> But in the area of floating point, I would argue that Lisp is just as
> broken as most other languages. For the average computer programmer,
> floating point is an accident waiting to happen, not the ideal default.
> Nor can it be said that Common Lisp is the best at supporting this
> format, which admittedly has its uses. Where's directed rounding mode
> support, or control over exception handling?

If you examine George Bush's recent inaugural address, you'll find
lots of similar desire to end all instances of certain classes of
problems for all time.

But it's not likely that the desire to do so will make it happen, and
there is credible reason to believe that his willingness to try will
bankrupt the United States and will leave us unable to pursue even
more modest goals in the future.

Lofty goals are great. Understanding one's own limitations is good, too.

There is a reason that people who program have to learn how to talk to
computers and don't get to just do it as a natural consequence of their
existing knowledge of English.

For example, arguments similar to those you and others have made here
are equally applicable to why LOOP should just implement English
instead of beating around the bush and using the pseudo-language fine
line distinctions that English speakers do not use. English does not
make the "for/with" distinction that LOOP does, for example. In
English, for and with are often synonyms in the way LOOP uses them,
and certainly do not have a scoping significance such as LOOP gives
them.

Formal languages are just that. Formal. They mean what they are
defined to mean and not otherwise. Informal languages, like English,
are maleable, but make very bad programming languages as a consequence.

If you're willing to leave aside "mere" concerns of practicality and
instead to take it as a given not worthy of discussion that you have
access to unlimited cash resources (yes, the changes you propose can
be expressed in cash terms, running probably into the many millions of
dollars), that compatibility with existing practice doesn't matter,
that your point of view is canonically right and will conflict with no
other way of life anywhere (i.e., that people will throw roses as you
parade the streets in victory), and that everyone thinks this is the
one and only one central problem perturbing the world today, I'm not
sure why you're wasting your time here on petty language politics.
There's probably a job waiting for you in the US White House...

John Thingstad

unread,
Feb 7, 2005, 3:00:40 PM2/7/05
to
On Mon, 07 Feb 2005 13:51:17 -0500, Cameron MacKinnon
<cmack...@clearspot.net> wrote:

>
> But in the area of floating point, I would argue that Lisp is just as
> broken as most other languages. For the average computer programmer,
> floating point is an accident waiting to happen, not the ideal default.
> Nor can it be said that Common Lisp is the best at supporting this
> format, which admittedly has its uses. Where's directed rounding mode
> support, or control over exception handling?

I am not sure there is a grail that eliminates all errors.
There is no general way to eliminate roundoff error.
I have taken a sideways glance to Mathematica.
Here the epsilon given to routines is implicit unless specified.
This can, however, cause other more subtle bugs.
I have previously argued that a basic course in numerical analysis
should be a part of a computer science curriculum.
I think education raher than sweeping the problem under the
carpet is the way to go here.

--
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/

Christopher C. Stacy

unread,
Feb 7, 2005, 4:03:42 PM2/7/05
to
t...@sevak.isi.edu (Thomas A. Russ) writes:
> It's actually too bad that the letter "d" is already taken for double
> float, since it would have been a nice suffix to use for decimal
> floats.

How about "$".
Just throwing in my $.02

Christopher C. Stacy

unread,
Feb 7, 2005, 4:09:56 PM2/7/05
to
Kent M Pitman <pit...@nhplace.com> writes:
> For example, arguments similar to those you and others have made here
> are equally applicable to why LOOP should just implement English

Date: Thursday, 18 November 1982 17:49-EST
From: Alan Bawden <ALAN at SCRC-TENEX>
To: INFO-COBOL, GMP
Re: [acw: LET'S -- a new looping macro for lisp]

Date: Wednesday, 17 November 1982 15:46-EST
From: Dick
Sender: DICK at MIT-OZ
To: *its at MIT-OZ, info-lispm at MIT-OZ, info-lisp at MIT-OZ
Re: LetS -- a new looping macro for lisp

LetS is a new Lisp looping macro which makes it possible to
write a wide class of loops as simple expressions. For example,
in order to sum up the positive elements of the one
dimensional array A one need only wirte:

(Rsum (Fgreater (Evector A)))

LetS is described fully in AIM-680 which has just appeared.
I will give a talk describing LetS in a few weeks.

LetS is compatably with both MacLisp and LispMachine Lisp.
It exists on the directories LIBSLP and LMLIB.

Try it you will like it.

Dick Waters

Send all comments etc. to Dick@OZ.


Date: Wednesday, 17 November 1982, 17:29-EST
From: Allan C. Wechsler <acw at scrc-vixen>
To: BSG, fun
Re: LET'S -- a new looping macro for lisp

LET'S is a new Lisp looping macro which makes it possible to
write a wide class of loops as simple expressions. For example,
in order to sum up the positive elements of the one
dimensional array A one need only write:

(LET'S SUM UP THE POSITIVE ELEMENTS OF THE ONE-DIMENSIONAL ARRAY A)

and all of LMFS can be compressed to

(LET'S HAVE A SUPER WINNING FILE SYSTEM THAT DOES THE RIGHT THING
ALL THE TIME)

For those who like to debug, you can leave off the ALL THE TIME modifier.

--- Allan

Christophe Turle

unread,
Feb 7, 2005, 4:21:59 PM2/7/05
to
"Christophe Rhodes" <cs...@cam.ac.uk> a écrit dans le message de news:
sqk6pke...@cam.ac.uk...

> Given this, do you really think it's sensible to require your
> transmitting frequency to be printed and treated as exactly 201.005296
> MHz?

Yes it is. Because this value will be sent to end users. And i'm sure that
they want to see the exact value printed on their screen.


--
___________________________________________________________
Christophe Turle.
sava preview http://perso.wanadoo.fr/turle/lisp/sava.html
(format nil "~a@~a.~a" 'c.turle 'wanadoo 'fr)


Christophe Turle

unread,
Feb 7, 2005, 4:31:08 PM2/7/05
to
"Thomas A. Russ" <t...@sevak.isi.edu> a écrit dans le message de news:
ymiy8e0...@sevak.isi.edu...

Thx. Having some roots in AI, i will gladly check it ;)

Christophe Turle

unread,
Feb 7, 2005, 4:35:26 PM2/7/05
to
"Barry Margolin" <bar...@alum.mit.edu> a écrit dans le message de news:
barmar-282AD3....@comcast.dca.giganews.com...
> In article <420670c4$0$958$626a...@news.free.fr>,

> "Christophe Turle" <ctu...@nospam.com> wrote:
>
>> It works with double float. But the point is : why MUST i care about
>> float
>> type EVEN if i'm not concerned with optimization ???
>
> Because you're not the only programmer, and other programmers have
> concerns different from yours. The language has to cater to a wide
> variety of needs. For many of them, floating point is the proper tool,
> and CL provides it, just like most other languages.
>
> If you don't need floating point, don't use it. But it seems really
> conceited of you to expect that the language should be designed to
> facilitate your specific application rather than others.

The problem is that you can always convert rational to float but not the
contrary.

This is the 'objective' ;) reason i think rational should be the default
interpretation, not because this suit best my needs.

It is loading more messages.
0 new messages