[comp.lang.postscript] Bug in PostScript math

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