[gs-devel] Re: gs-devel Digest, Vol 6, Issue 9

ORIMP18 owl at orimp.com
Mon Feb 16 16:14:23 PST 2004


 > From gs-devel-bounces at ghostscript.com Mon Feb 16 13:04:44 2004
 > Subject: gs-devel Digest, Vol 6, Issue 9
 > ...
 > ----------------------------------------------------------------------
 > 
 > Message: 1
 > Date: Mon, 16 Feb 2004 07:48:13 -0700 (MST)
 > From: "Nelson H. F. Beebe" <beebe at math.utah.edu>
 > Subject: [gs-devel] Re: The right formula for rounding
 > To: gs-devel at ghostscript.com
 > Cc: beebe at math.utah.edu
 > Message-ID: <CMM.0.92.0.1076942893.beebe at psi.math.utah.edu>
 > 
 > "Igor V. Melichev" <igor.melichev at artifex.com> writes:
 > 
 > >> The correct rounding formula from math is
 > >>
 > >>        i =  (int)(x + 0.5)
 > 
 > Careful; that is true only for nonnegative x.  More generally,
 > you want
 > 
 > 	i = (int)((x >= 0.0) ? (x + 0.5) : (x - 0.5));

Even this conversion must be applied with caution, as it rounds away
from the origin (-1.5 ==> -2, 1.5 ==> 2) as opposed to rounding toward
the larger value (-1.5 ==> -1, 1.5 ==> 2).

Such rounding is consistent only if the origin is in some way meaningful
for symmetry purposes. In most graphics this is not the case: the origin
is an arbitrarly chosen point, and there is no reason for rounding away
from it as opposed to any other point. Hence, my usual preference is to
consistently round up or down, using one of the following:

    i = (int)floor(x + 0.5)      /* round up */
    i = (int)ceil(x - 0.5)       /* round down */

Most modern compilers will inline the floor/ceil functions, and most
modern floating point processors provide hardware to implement them,
so this form involves a negligible performance penalty as compared with
simple casting.

                                                  Jan Stoeckenius
                                                  kiwi at orimp.com



More information about the gs-devel mailing list