caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: peio <peio.borthelle@gmail.com>
To: caml-list@inria.fr
Subject: [Caml-list] truncated division, remainder and arithmetics
Date: Wed, 27 Jan 2016 01:34:47 +0100	[thread overview]
Message-ID: <1453854887.31205.2.camel@gmail.com> (raw)

Good evening,


while doing some modular arithmetic I discovered that OCaml uses the
'truncated division' convention for the `/` (quotient) operator.
Actually this convention may seem innocent but it greatly affects the
`mod` (remainder) operator: the sign of the result is the same as
dividend.

After some research I realized that lots of people (D.Knuth!)
criticized this convention in favor of floored division (sign of
remainder same as divisor) or euclidean division (remainder always
positive). I know such a key component of the language isn't likely to
be changed but I would like to get some of the rationals behind this
decision.


I can't think of any case in which the current behavior more natural
but there are clearly situation giving weird results: I encountered one
while multiplying big numbers modulo 2**62 (on 64-bit machine): as
`max_int` is 2**62 - 1 the product could overflow and become negative.
Consequently one can't just write `(a * b) mod m` to get the result of
multiplication on the group Z/mZ if a and b are bigger than 2**31.

The workaround I found was to redefine quotient and remainder to follow
floored division convention:
let rem a b = ((a mod b) + b) mod b
let quo
a b = (a - rem a b) / b
Does anyone see a cleaner way to do it?

I don't know anything about division algorithm, but is it actually
easier/faster to implement the truncated division instead of the
floored division? Is there any other reason I missed to choose
truncated division?


At last another thing that (slightly) bugs me: why don't `ceil` and
`floor` have the type `float -> int`? Because the inherent definitions
of these functions talks about integers, not floats (floor(x) is the
biggest integer less than x). Indeed the `int_of_float (ceil x)` is a
very common pattern (according to some very unscientific searching
through github code search). Maybe even more subtle is that `truncate`
has type `float -> int`. In my opinion the type `float -> float` would
be more appropriate here because the truncation operation is about
approximating a real number with a decimal (we already got
`int_of_float` for rough converting).


cheers,
peio

             reply	other threads:[~2016-01-27  0:34 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-27  0:34 peio [this message]
2016-01-27  9:56 ` François Bobot
2016-01-27 10:02 ` Hendrik Boom
2016-01-27 10:18 ` Xavier Leroy
2016-01-28 19:03   ` peio

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

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

  git send-email \
    --in-reply-to=1453854887.31205.2.camel@gmail.com \
    --to=peio.borthelle@gmail.com \
    --cc=caml-list@inria.fr \
    /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 NNTP newsgroup(s).