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 -----