NICE-ESG-Libs Digest Sun, 11 Jun 95 Volume 1 : Issue 253
Today's Topics:
Power operator
NICE Eiffel Standards Group -- Library Committee Mailing List
To post to list:
NICE-ESG-Libs@atlanta.twr.com
To send mail to the Chairman of the committee:
NICE-ESG-Libs-chair@atlanta.twr.com
Administrative matters (sign up, unsubscribe, mail problems, etc):
NICE-ESG-Libs-request@atlanta.twr.com
Date: Sun, 11 Jun 95 15:33:01 PDT
From: bertrand@vienna.eiffel.com (Bertrand Meyer)
Subject: Power operator
To: NICE-ESG-Libs@atlanta.twr.com
Here is a note from Paul Dubois about the power operator.
I am not endorsing or disendorsing it, just forwarding it as
further enlightenment.
-- BM
----- Begin Included Message -----
From dubois@kristen.llnl.gov Tue Jun 6 11:23:56 1995
Date: Tue, 6 Jun 1995 11:16:17 +0800
To: bertrand@eiffel.com
Cc: nag-ise@vienna.eiffel.com
Subject: Re: Power operator
Your old basic Fortran person wants to be able in Eiffel to write:
x^2
and
x^y
without worrying about it. I am a big boy and I understand that certain
combinations of x and y might raise an exception.
The contract between me and Fortran is, I write an algorithm that won't
blow, and you execute it without looking. If something goes wrong, I'll
be waiting for the SIGFP.
(See discussion of this disgustingly reprobate attitude below).
What I hope is that the compiler is smart enough to spot things like
2^32
x^2
x^3
x^0.5
and generate appropriate optimizations. Fortran compilers, for example,
are smart enough not to do x**(small integer) by exponentiation.
Now, the attitude above is not an Eiffel attitude with respect to safety.
Persons without a disgusting past in Fortran want a precondition on
x^y so that in theory one could check before exponentiating. Fact: it will
never happen. I'm not going to write:
if (x1-x2).exponentiable(2) and (y1-y2).exponentiable(2) then
z := (x1-x2)^2 + (y1-y2)^2
if z >= 0 then
z := z.sqrt
else
error code
else
error code
end
That is fantasy island. How the hell would I write the error code without
calling raise anyway? No, I want to write
z := ((x1-x2)^2 + (y1-y2)^2).sqrt
People just don't check the contract on this sort of thing, they have
designed the algorithm to avoid the problem in the first place. (As here,
where all the checking is a waste of time).
This is one area where exception handling is appropriate. An error in x^y
should be thought of as "rare". You aren't proposing that exponentiable(y)
is going to check for possible overflow, are you? It would be so expensive
as to be ludicrous.
It might be easier for compiler writers to optimize x^2 if only integers are
allowed, but it doesn't do anything for the user. Fortran people who have
to use C hate the fact that the compiler writers voted for themselves
instead of for the users and that x^2 and x^y have to be expressed
differently.
To give the members of the committee some idea of what we usually do,
here is some typical Fortran from one of our codes. Try to
imagine this mess with precondition checking added. No way.
subroutine grwthrt(iopt)
Use(RunParm)
Use(Hydro)
Use(Light)
Use(Plasma)
Use(MiscField)
integer iopt
real knlocal,kbragk,keppln
real flhere, press, source, premlt, pkl, rootsq
real grmax
integer ix, iy, iz
flhere=1.
do iz=0,nz
press=cs(iz)*cs(iz)*atwt
if(ilangd .eq. 1)flhere=flangd(iz)
source=ienergy*nuabs(iz)*4*flhere/(dens0(iz)*te0(iz))
premlt=dens0(iz)*zbar(iz)*alpha(iz)/press
do ix=-nx,nx-1
do iy=-ny,ny-1
kbragk=kthcoef(iz)*sqkpsq(ix,iy)
pkl=k0lmfp(iz)*sqkpsq(ix,iy)
kav=exp(-sclknl*(pkl/sqrt(zbar(iz)))**expknl)
knlocal=kthcoef(iz)/(1.+46.74*(pkl)**1.148)
keppln=kthcoef(iz)/(1.+48.4*pkl**1.333)
knlocal=kav*knlocal+
& (1.-kav)*kthcoef(iz)*khp(iz)/(khp(iz)+kbragk)
knlocal=(1-ikeppln)*knlocal+ikeppln*keppln
divvo (ix,iy)=source*press/(zbar(iz)*knlocal)
cc..
if(iopt .eq. 0)divvo(ix,iy)=0.
tarr1(ix,iy)=(2*ipond*kpsq(ix,iy)+divvo(ix,iy))*premlt
rootsq=2*tarr1(ix,iy)-kpsq(ix,iy)*kpsq(ix,iy)
if(rootsq .gt. 0.)then
shift(ix,iy)=sqrt(rootsq)/(2*k0(iz))
else
shift(ix,iy)=1.e-10
endif
enddo
enddo
cc..c...find maximum spatial growth rate at z
grmax=0.
do ix=-nx,nx-1
do iy=-ny,ny-1
grmax=max(grmax,shift(ix,iy))
if(shift(ix,iy) .eq. grmax)kpsqm(iz)=sqkpsq(ix,iy)
enddo
enddo
kappa(iz)=grmax
enddo
return
end
Ugly, ain't it. (I didn't write this, of course).
Paul Dubois
----- End Included Message -----

|
|