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

Gnu Common Lisp HELP!

40 views
Skip to first unread message

Ola Andersson

unread,
Jan 11, 1996, 3:00:00 AM1/11/96
to
Hi!

I am a new Lisp user and I would like to know why I get this result:
(SETQ INTEREST-RATE 0.1)
0.10000000001

I am using gcl v2.1. (What is the latest version?)

--
Ola Andersson Email: ra...@ling.umu.se
Research Engineer WWW:
http://www.ling.umu.se/~rand
Department of Phonetics Phone: +46 90 16 95 48
Umea University Fax: +46 90 16 63 77

Erik Naggum

unread,
Jan 11, 1996, 3:00:00 AM1/11/96
to
[Ola Andersson]

| I am a new Lisp user and I would like to know why I get this result:
| (SETQ INTEREST-RATE 0.1)
| 0.10000000001

because it's correct. 0.1 cannot be expressed accurately with floating
point. instead of floating point, use rational numbers, such as 1/10.

representing and computing monetary values with floating-point is a
well-known "sin".

note that the Common Lisp `round' function rounds to even integers. this
is the numerically correct solution, and works out best with money, as
well. most people don't understand this, and insist on small errors. some
national regulations even force people to be screwed by rounding errors.
you may need to take this into account (pun intended).

| I am using gcl v2.1. (What is the latest version?)

version 2.2 has been released. look in math.utexas.edu:/pub/gcl.

#<Erik 3030380960>
--
the problem with this "information superhighway" is mainly that if you ask
people to go play in it, they don't even understand when they get run over.

Mike McDonald

unread,
Jan 11, 1996, 3:00:00 AM1/11/96
to

In article <19960111...@arcana.naggum.no>, Erik Naggum <er...@naggum.no> writes:

>| I am using gcl v2.1. (What is the latest version?)
>
>version 2.2 has been released. look in math.utexas.edu:/pub/gcl.

Try ftp.ma.utexas.eduL/pub/gcl instead.

>ftp math.utexas.edu
Connected to fireant.ma.utexas.edu.
220-
220-Hello unk...@sgigate.SGI.COM
220-This is not the ftp server of UTMATH
220-Please use ftp.ma.utexas.edu for anonymous ftp
220-
220 fireant FTP server (SunOS 4.1) ready.
Name (math.utexas.edu:mikemac): anonymous
331 Guest login ok, send ident as password.
Password:
550 Can't set guest privileges.
Login failed.
ftp> quit
--

Mike McDonald
mik...@engr.sgi.com

William D Clinger

unread,
Jan 12, 1996, 3:00:00 AM1/12/96
to
In article <19960111...@arcana.naggum.no>

Erik Naggum <er...@naggum.no> writes:
>[Ola Andersson]
>
>| I am a new Lisp user and I would like to know why I get this result:
>| (SETQ INTEREST-RATE 0.1)
>| 0.10000000001
>
>because it's correct. 0.1 cannot be expressed accurately with floating
>point...

It would be more correct for the implementation to print 0.1, and many
of us would prefer that. Let's suppose, for the sake of concreteness,
that the implementation uses IEEE double precision to represent numbers
like 0.1. (The story would be similar if we assumed single precision.)

The IEEE double precision number that is closest to 0.1 is

0.1000000000000000055511151231257827021181583404541015625.

Most people don't want to see the low-order digits of this number,
so almost all output routines will round it to fewer digits before
it is printed. The interesting question is "How many digits should
be printed?"

Some implementations always round to some fixed number of digits
(counting from the first nonzero digit). If IEEE double precision
is used, then an implementation that always rounds to 17 digits would
print 0.10000000000000001, while an implementation that always rounds
to 16 digits would print 0.1000000000000000 or 0.1. The problem with
rounding to only 16 digits is that two distinct IEEE double precision
numbers would sometimes be printed the same way.

A better way, in my opinion, is to round to the smallest number of
digits that would allow the exact value of the floating point number
to be recovered by reading the printed value. This is required by
the IEEE/ANSI standard for Scheme, and is also done by some
implementations of Common Lisp. If an implementation does this,
then the floating point number that is obtained by reading "0.1"
will be printed as "0.1". Furthermore distinct floating point
numbers will always print differently.

By the way, I concur with Erik Naggum's recommendation that monetary
quantities, and related quantities such as interest rates, should
be represented by exact rational numbers, not inexact floating
point numbers.

Floating point arithmetic is inherently inexact. It is useful for
rapid calculations of quantities whose exact values can never be
known anyway, such as quantities obtained by scientific measurements
and used in engineering.

William D Clinger

Erik Naggum

unread,
Jan 12, 1996, 3:00:00 AM1/12/96
to
a clarification of my previous article may be necessary if you're
unfamiliar with rounding functions.

| note that the Common Lisp `round' function rounds to even integers.

rounding functions differ in behavior for the value N + 1/2. some round up
to N + 1, some round down to N, some round to the nearest even integer,
some round towards zero (down for positive values, up for negative values),
some round towards infinity (the opposite). for all other values, these
functions agree that N + F, for -1/2 < F < 1/2, rounds to N. here's a
breakdown that might illustrate this mess:

up down even zero infinity
-4.7 -5 -5 -5 -5 -5
-4.5 -4 -5 -4 -4 -5
-4.2 -4 -4 -4 -4 -4
-3.5 -3 -4 -4 -3 -4
3.5 4 3 4 3 4
4.2 4 4 4 4 4
4.5 5 4 4 4 5
4.7 5 5 5 5 5

I hope this forestalls any confusion.

note that when computing values with floating point representation, losing
bits of precision requires rounding. very frequently (if not exclusively),
one loses exactly one bit of precision, and when this happens, the smallest
accumulated rounding error is obtained by rounding to even.

Common Lisp offers a number of other float-or-rational-to-integer
conversion functions, as well: floor (truncate towards negative infinity),
ceiling (truncate towards positive infinity), and truncate (towards zero).

#<Erik 3030395912>

Wolfgang von Hansen

unread,
Jan 12, 1996, 3:00:00 AM1/12/96
to
I just had a look at the FAQ. Some implementations of Lisp convert the Lisp
source into a C source for compilation.

Are there programs that do the reverse (translating an arbitrary C source
into a set of Lisp functions)? If not, what is the main reason against such
a program?

Wolfgang
--
| vha...@ipf.bau-verm.uni-karlsruhe.de
(_(__)_) | S: Laptop/Notebook mit Festplatte; Preis niedrig
|oo| |
(..) | Hier koennte auch Ihre Anzeige stehen!

Kelly Murray

unread,
Jan 12, 1996, 3:00:00 AM1/12/96
to
In article <4d646o$g...@nz12.rz.uni-karlsruhe.de>, vha...@ipfy.bau-verm.uni-karlsruhe.de (Wolfgang von Hansen) writes:
>> I just had a look at the FAQ. Some implementations of Lisp convert the Lisp
>> source into a C source for compilation.
>>
>> Are there programs that do the reverse (translating an arbitrary C source
>> into a set of Lisp functions)? If not, what is the main reason against such
>> a program?

The main reason against it is that C can't be efficiently translated into
Common Lisp primarly because of C pointers. The "&" operator just doesn't
have an efficient correspondance in CL, as well as doing pointer arithmetic,
If the C program doesn't use "&" or other pointer arithmetic,
then it isn't a problem doing the translation. How many C programs don't
use pointers? very few.

I've actually done a C->CL translator where the "&" operation
gets translated into consing a "pointer" object that has a base + offset
fields in the object: (BTW, the code isn't available, sorry)

void *foo = &array[10];
void *bar = foo + 4;

=> (roughly)

(let ((foo (make-pointer :base array :offset 10))
(bar (make-pointer :base (pointer-base foo)
:offset (+ (pointer-offset foo) 4)))

This works, but it's highly inefficient as it conses like mad,
and violates the rational of having pointers in C.
(With a 64-bit pointer implementation of Lisp, you could avoid the consing)
But it was a good attempt at providing "backward" compatibility
for a new C language (I called it CRISP) where pointers are "obsolete".
However, you'd get garbage-collection and CLOS, and in my case, parallelism.
Note that JAVA is very similiar (C(++) w/o pointers)
and thus should be easy to translate/compile into CL.

-Kelly Murray k...@franz.com http://www.franz.com

Jeff Dalton

unread,
Jan 13, 1996, 3:00:00 AM1/13/96
to
In article <4d646o$g...@nz12.rz.uni-karlsruhe.de> vha...@ipfy.bau-verm.uni-karlsruhe.de (Wolfgang von Hansen) writes:
>I just had a look at the FAQ. Some implementations of Lisp convert the Lisp
>source into a C source for compilation.
>
>Are there programs that do the reverse (translating an arbitrary C source
>into a set of Lisp functions)? If not, what is the main reason against such
>a program?

To answer this, it's necessary to consider two cases.

Lisp-to-C compilers use C as a kind of portable assembly language.
Rather than compile to native code, they compile to C and let the C
compiler worry about the native code. The C code they emit might
be somewhat readable, but you wouldn't want to treat it as a C
program that you could develop and modify in C. It may use
different calling conventions than C (passing args on a different
stack), and it tends to be full of low-level, rather cryptic-looking
stuff.

You don't see C-to-Lisp compilers of this sort, because C is
generally lower-level than Lisp and because on most machines C
compilers are available before Lisp compilers. It might make
sense for a C compiler on a Lisp machine to compile to Lisp.
I don't know whether any actual Lisp machine C compiler worked
that way.

The other case is what's usually called a Lisp-to-C "translator".
Such systems may try to produce C that you could then treat as an
ordinary C program. The code will tend to be more readable, at least.
So if you wanted to move your development work from Lisp to C, this
might be one way to get started. Lisp-to-C translators may also try
to let you combine Lisp and C more easily. (For instance, you usually
have to load compiled C into a Lisp system to use Lisp and C together,
rather than just link together Lisp and C object files. A translator
might aim for the "link together" case.)

Both of the reasons against C-to-Lisp compilers also apply here.
For instance, C often works with pointers, which aren't easily
expressed in Lisp; and C expresses type information in more
cases than Lisp. So writing a good translator might be difficult.
You'd probably have to choose between natural-looking Lisp that
was less efficient than the C version and C-like Lisp that was
cluttered with low-level stuff.

Now, the compiler case depends almost entirely on practical
issues. Lisp implementors may want to take advantage of C
compilers that already exist; C implementors generally aren't
in that position. The translator case adds another element.
Lisp is seen as maybe good for development but poor for
delivery. So, for that and other reasons, moving from Lisp
to C is more popular than moving from C to Lisp.

However, there aren't many Lisp-to-C translators, so far as I know.
There are more (though still not very many) Lisp-to-C compilers.
So we should be careful about drawing strong conclusions.

Still, there are programs that translate at least some C
data structure definitions into Lisp or into something
Lisp-implementation-specific that lets C objects be
manipulated from Lisp.

-- jeff

Erik Naggum

unread,
Jan 14, 1996, 3:00:00 AM1/14/96
to
[Pierre Parquier]

| I beg to disagree. CoBOL has addressed this issues for decades (its
| core business, so to speak), and felt no need for rational. Why?

because Cobol has a different set of types than Common Lisp has, obviously.
case in point: Common Lisp does not have fixed-point numbers, and Cobol
does not have ratios. you pick what you need from what you can. since
this is not comp.lang.cobol, but comp.lang.lisp, I thought my answer should
address this audience. I did not intend to argue against other language's
more (or less) appropriate types for representing monetary values, only to
argue against the usage of floating point to represent monetary values when
Common Lisp offers rationals, which is a far better type, especially with
bignums for both numerator and denominator.

| First, the problem with rational for monetary matters: there are not
| enough operations defined on ratios for accounting. Eg you cannot
| compute a monthly interest rate give a yearly interest rate.

this I do not understand. interest rate and the period of compounding are
separate concepts, at least as I learned accounting (it has been 15 years
-- updates accepted), and one may very well divide an annual interest rate
by 12 (a well-defined operation over ratios) to obtain a monthly interest
rate if the period of compounding is the same (a year), but since annual
compounding cannot be turned into monthly compounding, there is no way you
can compute a monthly interest rate that will yield the same compound
interest without knowing the term of the loan or the investment.

| Second, how do CoBOL folks manage monetary items: they use integers
| for quantities (ok, fixed point values, but that's essentially the
| same, and that's very different from a ratio), rates to be applied
| only to these quantities, and reserve floats for more complex
| computation. Using float all around is a beginner mistake in CoBOL.

this, too, I do not understand. a fixed-point value is a ratio with a
constant denominator, is it not? I donated my copy of the ANSI Cobol
standard to my University's computer lab 5 years ago, but from my
admittedly rusty memory of reading it, there should be no difference from
computing with ratios. transcendental operations are well-defined for
ratios; they are coerced to floating-point -- coercing back to rational
with a constant denominator entertains the same notion of error that you
have in fixed-point numbers. (transcendental operations may be computed by
mathematical series of fractions and non-transcendental operations. except
for the obvious issue of speed, there is no need to leave rational space.)

| In finance, the story is very different, and the quantities are more
| like physical quantities, therefore floats are usually prefered.

I had not thought of that, but it is clearly a valid observation.

#<Erik 3030650282>

Pierre Parquier

unread,
Jan 14, 1996, 3:00:00 AM1/14/96
to

wdc> I concur with Erik Naggum's recommendation that monetary
wdc> quantities, and related quantities such as interest rates,
wdc> should be represented by exact rational numbers, not inexact
wdc> floating point numbers.

I beg to disagree. CoBOL has addressed this issues for decades (its
core business, so to speak), and felt no need for rational. Why?

First, the problem with rational for monetary matters: there are not


enough operations defined on ratios for accounting. Eg you cannot
compute a monthly interest rate give a yearly interest rate.

Second, how do CoBOL folks manage monetary items: they use integers


for quantities (ok, fixed point values, but that's essentially the
same, and that's very different from a ratio), rates to be applied
only to these quantities, and reserve floats for more complex
computation. Using float all around is a beginner mistake in CoBOL.

The justification for this is that in accounting, there *is* an notion
of error (unlike ratio), but on the contrary to IEEE floats, it is
under total control (I mean of the average acounting clerk or
programmer, quite unlike the average engineer).

In finance, the story is very different, and the quantities are more

like physical quantities, therefore floats are usually prefered. But
I felt you were more in the accounting sphere.

Bottom line is that if you are more serious about accounting in Lisp,
you should create your monetary classes, whose attributes are:
accuracy (to the cent, tenth of a cent...), number of minute units (an
integer), monerary unit (USD, GBP,...), perhaps another class for
rates, maybe more.

Now let's be real, for toy accounting (ie no error programming),
floats are good enough, with proper output formating.

__________________________________________________
Pierre Parquier parq...@ilog.fr
ILOG S.A. http://www.ilog.com
*** Use Lisp for C++ libraries: use Ilog Talk! ***

Pierre Parquier

unread,
Jan 15, 1996, 3:00:00 AM1/15/96
to

parquier> CoBOL has addressed this issues for decades (its core
parquier> business, so to speak), and felt no need for rational.
parquier> Why?

erik> because Cobol has a different set of types than Common Lisp
erik> has, obviously. case in point: Common Lisp does not have
erik> fixed-point numbers, and Cobol does not have ratios. you pick
erik> what you need from what you can.

Not so. CoBOL folks get what they need for their application field,
because they define the language for their needs and make it evolve.
There is nothing special about CoBOL: it is a community of intelligent
people. They don't use ratio for accounting, because accounting
requires something else.

Conversely you can easily implement your fixed point numbers in Lisp.
Extensibility of Lisp is usefull, let it show!

erik> since this is not comp.lang.cobol, but comp.lang.lisp, I
erik> thought my answer should address this audience.

Same with me. To understand how to use Lisp (or specifically Common
Lisp) in an unusual way (accounting), we must peek in languages
already addressing the issue. That's a cheap way to avoid
re-inventing the wheel, or, equally evil, commit known mistakes.

erik> I did not intend to argue against other language's more (or
erik> less) appropriate types for representing monetary values, only
erik> to argue against the usage of floating point to represent
erik> monetary values when Common Lisp offers rationals, which is a
erik> far better type, especially with bignums for both numerator and
erik> denominator.

Suggesting rationals for this is precisely the point I am chalenging.

parquier> First, the problem with rational for monetary matters:
parquier> there are not enough operations defined on ratios for
parquier> accounting. Eg you cannot compute a monthly interest rate
parquier> given a yearly interest rate.

erik> this I do not understand. [...] one may very well divide an
erik> annual interest rate by 12

Ahem, this is wrong. I am sorry to get into accounting basics in
comp.lang.lisp, but once again, I think it is releavant to the
question of properly using numbers in Lisp (or Common Lisp in
particular).

To get a monthly interest rate, you must use the twelvth root
(YearRate^(1/12)). That computation is not rational.

I forgot to make an other point against rationals in accounting
(although I referred to it when visiting how CoBOLers work): many
computations don't match an exact value, and you have to introduce an
error. When you split $10 in three, your result have to be an integer
amount of cents (or dollars, or tenth of a cent, you decide), and you
want to have unequal yet predicatable values. Same thing when you
apply a rate: what's 11% of $1.23?

From the two arguments above, it stems that rational are inappropriate
because:

- their domain is too restricted to match all operation (contrary to
floats)

- they are too precise to support natural rounding (contrary to
integers, or fixed point)

parquier> [...] fixed point values, but that's essentially the same,
parquier> and that's very different from a ratio

erik> this, too, I do not understand. a fixed-point value is a ratio
erik> with a constant denominator, is it not? there should be no
erik> difference from computing with ratios

The set of ratios with a given denominator is not usable as ratios,
you can't define rational division on it: what is 1/100 / 10/100?
Such set of numbers (ie the fixed point numbers) without division (or
with euclidian division only) is not a set of rational nubers, it is a
set of (poorly disguised) integers.

erik> except for the obvious issue of speed, there is no need to
erik> leave rational space.

I see this differently: there is no reason to leave integers (or fixed
point, if you will) for ratios to manipulate monetary units. And
there are two reasons not to adopt rationals: their performance is
hardly predictable, and their comparative cost is huge.

And again, if you want to keep it simple, just use floats and be
carefull with the output. That's how I program my payrolls at home.

Jonathan Millen

unread,
Jan 16, 1996, 3:00:00 AM1/16/96
to
Q: does Gnu Common Lisp support mixed-case symbols?
I have version 2.2 and it does not recognize readtable-case,
which according to Steele's book should be switchable from
the normal ":upcase" mode to ":preserve".

Jeff Dalton

unread,
Jan 17, 1996, 3:00:00 AM1/17/96
to
In article <PARQUIER.96...@halles.ilog.fr> parq...@halles.ilog.fr (Pierre Parquier) writes:
>wdc> I concur with Erik Naggum's recommendation that monetary
>wdc> quantities, and related quantities such as interest rates,
>wdc> should be represented by exact rational numbers, not inexact
>wdc> floating point numbers.
>
>I beg to disagree. CoBOL has addressed this issues for decades (its
>core business, so to speak), and felt no need for rational. Why?

Does COBOL use decimal floats or binary?

-- jd

0 new messages