werner@aecom.yu.edu (Craig Werner) (08/10/89)
I recently encountered a problem that seems to be do to a bug in the PostScript arithmetic routines built into an Apple LaserWriter IINT. Consider the following: 1) divide 200 by 5, save the 40 in a variable 2) add 200, later subtract 200 3) divide the variable byt the current value, the answer is 1.0 4) truncate the 1.0, the answer should still be 1.0. Now divide 200 by 3, saving 66.6667. When you truncate the 1.0 in step 4, the result is 0.0 If you don't believe me, run the following code fragment with the variable "nlines" (~4 lines from the bottom) set to either 5 or 3. Please note, however, that since the truncation is necessary in the logic of the loop, the bug causes an infinite loop. All the functionality of the following routine has been removed, only the logic and debugging statements remain. %!PS /inch {72 mul} def /str 11 string def /DEBUG { dup str cvs show ( ) show } def /Times-Roman findfont 8 scalefont setfont /COUNTER 0 def 1 inch 10 inch COUNTER 10 mul sub moveto /linMSEG { MZeroPoint sub /_finish exch def MZeroPoint sub /_start exch def _start DEBUG dup linelimit div DEBUG truncate DEBUG dup /Line exch def linelimit mul sub DEBUG /rstart exch def _finish Line linelimit mul sub DEBUG /rfinish exch def /COUNTER COUNTER 1 add def 1 inch 10 inch COUNTER 10 mul sub moveto copypage rfinish linelimit le {} { Line 1 add linelimit mul MZeroPoint add _finish MZeroPoint add linMSEG } ifelse } def /COUNTER 0 def /start 200 def /finish 400 def /length finish start sub def /nlines 3 def /MZeroPoint 200 def /linelimit length nlines div def start finish linMSEG -- Craig Werner (future MD/PhD, 4.5 years down, 2.5 to go) werner@aecom.YU.EDU -- Albert Einstein College of Medicine (1935-14E Eastchester Rd., Bronx NY 10461, 212-931-2517) "If it weren't for politicians, who would fashion disorder out of chaos."
zben@umd5.umd.edu (Ben Cranston) (08/11/89)
In article <2395@aecom.yu.edu> werner@aecom.yu.edu (Craig Werner) writes: > 1) divide 200 by 5, save the 40 in a variable > 2) add 200, later subtract 200 > 3) divide the variable byt the current value, the answer is 1.0 > 4) truncate the 1.0, the answer should still be 1.0. > When you truncate the 1.0 in step 4, the result is 0.0 Yeah, I was bit by something similar two weeks ago trying to implement a PostScript routine to expand tab stops. It took the current X position, subtracted off the left margin, and divided by the width of a character in the current (constant-width) font. Only trouble was that at the very beginning of the line the result was not zero but -1E-6 (a very small negative number). I certainly hope you take a course in floating point numbers someday, cause this sort of thing happens all the time. What you generate is just a whisker below 1.0, and the floating point to character routine actually TRANSLATES it as the string "1.0" but when you truncate it you get zero instead of one. Your best bet is to round the number up like this: whatever .5 add cvi fixes a lot of these errors. -- Sig DS.L ('ZBen') ; Ben Cranston <zben@umd2.UMD.EDU> * Computer Science Center Network Infrastructures Group * University of Maryland at College Park
werner@aecom.yu.edu (Craig Werner) (08/13/89)
In article <2395@aecom.yu.edu>, werner@aecom.yu.edu (Craig Werner) writes: > > I recently encountered a problem that seems to be do to a bug in > the PostScript arithmetic routines built into an Apple LaserWriter IINT. > > Consider the following: > 1) divide 200 by 5, save the 40 in a variable > 2) add 200, later subtract 200 > 3) divide the variable byt the current value, the answer is 1.0 > 4) truncate the 1.0, the answer should still be 1.0. > > Now divide 200 by 3, saving 66.6667. > When you truncate the 1.0 in step 4, the result is 0.0 > Let me restate the problem. I referred to the problem as a bug when the real problem is that it has been twelve years since I've encountered such an egregious arithmetic precision error. (The last time was on a TRS-80 Model I, Level I, system complete with 4K RAM.) Just out of curiousity, what is the precision of PostScript's floating point routines? It's obviously a lot less than I had expected. I'm still confused as to why cvs would report the number as 1.0 instead of what it really was. However, I've used this to my advantage, and a fix for the particular problem seems to be replacing truncate with 20 string cvs cvr truncate (11 string gives me a cvs rangecheck error, and at this point I'd rather not ask why.) -- Craig Werner (future MD/PhD, 4.5 years down, 2.5 to go) werner@aecom.YU.EDU -- Albert Einstein College of Medicine (1935-14E Eastchester Rd., Bronx NY 10461, 212-931-2517) "Sometimes you have to run as fast as you can just to stay in the same place."