unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: Mark H Weaver <mhw@netris.org>
To: guile-devel@gnu.org
Subject: Commentary: R6RS div0-and-mod0 vs Taylor's `round/'
Date: Sun, 30 Jan 2011 01:02:44 -0500	[thread overview]
Message-ID: <87sjwb0vzv.fsf_-_@yeeloong.netris.org> (raw)
In-Reply-To: <8762t72vrc.fsf@yeeloong.netris.org> (Mark H. Weaver's message of "Sat, 29 Jan 2011 17:24:55 -0500")

Hello all,

I decided to search for the rationale for the R6RS `div0-and-mod0' set
of operators.  Here's what I found from Will Clinger:

  http://srfi.schemers.org/srfi-77/mail-archive/msg00505.html

What I take from this is that the designers of the R6RS division
operators placed emphasis on the range of the remainder, to make it as
compact and predictable as possible.  The rounding policy of the
quotient is considered unimportant; it must be whatever makes the
remainder fit in the specified range.  In the case of integer inputs
with divisor D, both `mod' and `mod0' produce exactly D possible values,
and that set of values depends only on the magnitude of D, not on the
sign of N or D.

In contrast, Taylor Campbell's proposal puts all emphasis on the
rounding policy of his quotient operators, with the range of remainders
considered secondary.

  http://trac.sacrideo.us/wg/wiki/DivisionRiastradh

A case in point is Taylor's `round/' operator, which is _almost_
identical to the R6RS `div0-and-mod0'.  They only time they produce
different results is when the quotient is exactly half-way between two
integers, and for integer arguments this can happen only when D is even.
In this case, Taylor chooses to round to the even integer, and this
implies that the set of possible remainders is not D but rather D+1.

Another way to look at it is as follows: if you set D to some fixed
integer and look at the output of (mod N D) as N loops over all the
integers, then both R6RS `mod' and `mod0' will simply cycle through
exactly D possible outputs.  However, `round-remainder' does not quite
do this when D is even.  It will mostly cycle through its outputs,
except for the two most extreme values, which are hit only half as often
as all the others.  Each time around the cycle, it will alternate which
one it hits.  Basically, the minimum value of `mod0' has been split into
two different values in `round-remainder', increasing the total number
of possible values from D to D+1.  Personally, I think this is a poorly
designed set of division operators.

For those who are curious, given the contraints on `mod0's output range,
`div0's rounding policy turns out to be as follows: half-integer
quotients are rounded toward +inf when the divisor D is positive, and
toward -inf when D is negative.

Personally, I think that `div0-and-mod0' is far superior to `round/',
because I think the range of remainders is much more important than how
one rounds the half-integer quotients.

As for the difference between R6RS `div-and-mod' (Taylor's `euclidean/')
and `floor/', I don't think it matters much.  In the cases I know of
where the set of remainder values is important, D is generally positive,
in which case `floor/' and `euclidean/' are the same.

Taylor's `truncate/' (the same as R5RS quotient and remainder, as well
as the C operators `/' and `%') have a different problem.  If you use
the outputs of % to index into a table, typically the divisor D is fixed
but the dividend N may be less predictable.  In this case you must be
careful that the dividend N does not change sign.  If it does, the
remainder will change sign.  This is a possible source of bugs.

In some rare cases `truncate/' may truly be what you want, but in my
experience, `euclidean/' is the most generally useful, and `floor/' is
almost as good.  The primary advantage to `truncate/' is that it is what
most processors (and thus C) supports directly, and thus it can be
implemented much more efficiently than the other division operators.

      Mark



  reply	other threads:[~2011-01-30  6:02 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-26 16:32 [PATCH] First batch of numerics changes Mark H Weaver
2011-01-26 18:07 ` Mark H Weaver
2011-01-26 22:46 ` Mark H Weaver
2011-01-27 22:06   ` Mark H Weaver
2011-01-28 12:19     ` Andy Wingo
2011-01-29  0:05       ` Mark H Weaver
2011-01-29 11:29         ` Andy Wingo
2011-01-27 22:32   ` Mark H Weaver
2011-01-28 13:46   ` Andy Wingo
2011-01-28 14:44     ` Noah Lavine
2011-01-28 15:55       ` Andy Wingo
2011-01-29  8:20     ` Mark H Weaver
2011-01-29 17:42       ` Andy Wingo
2011-01-29 20:20         ` Mark H Weaver
2011-01-30 11:48           ` Andy Wingo
2011-01-29 17:50       ` Andy Wingo
2011-01-29 20:36         ` Mark H Weaver
2011-01-29 22:24         ` Mark H Weaver
2011-01-30  6:02           ` Mark H Weaver [this message]
2011-01-30 11:50           ` Andy Wingo
2011-01-30 12:12       ` Andy Wingo
2011-01-30 16:33         ` Mark H Weaver
2011-01-28 11:41 ` Andy Wingo
2011-01-28 23:36   ` Mark H Weaver

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87sjwb0vzv.fsf_-_@yeeloong.netris.org \
    --to=mhw@netris.org \
    --cc=guile-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).