Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

rem(X,Y) and mod(X,Y)

3,070 views
Skip to first unread message

Neng-Fa Zhou

unread,
Apr 14, 2008, 12:54:55 PM4/14/08
to
Anybody knows the difference between rem(X,Y) and mod(X,Y) in ISO Prolog?
The standard says that rem(X,Y) returns the integer remainder and mod(X,Y)
returns modulo, but gives no examples. By some definition, for example
http://mathworld.wolfram.com/Remainder.html, remainder looks like modulo.
Here are what from B-Prolog and SWI-Prolog:

B-Prolog:

3 mod 2=1
3 mod-2=1
-3 mod 2= -1
-3 mod-2= -1
3 rem 2=1
3 rem-2=1
-3 rem 2= -1
-3 rem-2= -1

SWI:

3 mod 2=1
3 mod-2=1
-3 mod 2= -1
-3 mod-2= -1
3 rem 2=0.5
3 rem-2= -0.5
-3 rem 2= -0.5
-3 rem-2=0.5

It seems that there is no difference betwen rem and mod in B-Prolog. Any
suggestions on what is compliant with the standard?

Cheers,
Neng-Fa

Jan Wielemaker

unread,
Apr 14, 2008, 5:24:25 PM4/14/08
to

I think this is a pretty old version of SWI-Prolog:

?- A is 3 rem 2.
A = 1.

Ulrich also pointed out that the implementation of mod/2 is broken for
negative values also in the latest version. I haven't studied the
details of his remarks and the standard yet.

Cheers --- Jan

Neng-Fa Zhou

unread,
Apr 14, 2008, 7:26:04 PM4/14/08
to

"Jan Wielemaker" <j...@nospam.ct.xs4all.nl> wrote in message
news:slrng07is...@ct.lan...

> On 2008-04-14, Neng-Fa Zhou <nz...@acm.org> wrote:
>> Anybody knows the difference between rem(X,Y) and mod(X,Y) in ISO Prolog?
> Ulrich also pointed out that the implementation of mod/2 is broken for
> negative values also in the latest version. I haven't studied the
> details of his remarks and the standard yet.

I don't know which implementation is correct. I'd like to know if anybody
who created the standard knows about the difference between mod and rem.

Cheers,
Neng-Fa


Joachim Schimpf

unread,
Apr 14, 2008, 8:33:07 PM4/14/08
to

To the best of my knowledge, the standard isn't terribly clear about that,
apart from requiring that // and rem go together such that
X =:= (X rem Y) + (X // Y) * Y.
without being specific about negative arguments, also for mod.

A few years ago I cleaned this up in ECLiPSe, following recommendations
by Richard O'Keefe. These go beyond the standard, but seem sensible and
consistent with many other languages:

X // Y division with truncated result
X rem Y remainder corresponding to //, in range -(Y-1)..Y-1
X div Y division with floored result (not in ISO)
X mod Y remainder corresponding to div, in range 0..Y-1

Such that X =:= (X rem Y) + (X // Y) * Y
and X =:= (X mod Y) + (X div Y) * Y.

This yields:

1 is 3 rem 2
1 is 3 rem -2
-1 is -3 rem 2
-1 is -3 rem -2

1 is 3 // 2
-1 is 3 // -2
-1 is -3 // 2
1 is -3 // -2

1 is 3 mod 2
-1 is 3 mod -2
1 is -3 mod 2
-1 is -3 mod -2

1 is 3 div 2
-2 is 3 div -2
-2 is -3 div 2
1 is -3 div -2


Cheers,
Joachim

Mats Carlsson

unread,
Apr 15, 2008, 4:02:36 AM4/15/08
to
On Apr 15, 2:33 am, Joachim Schimpf <jschi...@cisco.com> wrote:
> Neng-Fa Zhou wrote:
> > "Jan Wielemaker" <j...@nospam.ct.xs4all.nl> wrote in message
> >news:slrng07is...@ct.lan...
> >> On 2008-04-14, Neng-Fa Zhou <nz...@acm.org> wrote:
> >>> Anybody knows the difference between rem(X,Y) and mod(X,Y) in ISO Prolog?
> >> Ulrich also pointed out that the implementation of mod/2 is broken for
> >> negative values also in the latest version. I haven't studied the
> >> details of his remarks and the standard yet.
>
> > I don't know which implementation is correct. I'd like to know if anybody
> > who created the standard knows about the difference between mod and rem.
>
> To the best of my knowledge, the standard isn't terribly clear about that,

I disagree. The rules given in Section 9.1.3 of ISO/IEC 13211-1 seem
unambiguous to me, namely if Y=\=0 then:

mod(X,Y) = X-((X div Y)*Y)
rem(X,Y) = X-((X // Y)*Y)

where:

> X // Y division with truncated result

> X div Y division with floored result

This is consistent with:

> X mod Y remainder corresponding to div, in range 0..Y-1 if Y>0
or range Y+1..0 if Y<0
> X rem Y remainder corresponding to //, in range -(Y-1)..Y-1 if Y>0
or range Y+1..-(Y+1) if Y<0

> Such that X =:= (X rem Y) + (X // Y) * Y
> and X =:= (X mod Y) + (X div Y) * Y.

ISO, ECLiPSe and SICStus agree on this issue (div is not an evaluable
functor in SICStus, nor is it mentioned by ISO, as Joachim points
out).
--Mats

Jan Wielemaker

unread,
Apr 15, 2008, 4:37:11 AM4/15/08
to

Thanks to a patch by Ulrich that I found in my mailbos this morning,
SWI-Prolog now also agrees. Just out of curiosity, I think I only
used mod/2 with positive integers (nominator non-negative). Rem has
been broken totally for many years and mod has been broken for
negative integers until this morning. It was only Ulrich, adding more
ISO compliancy tests who finally found these issues.

What are the common usecases for rem/2 and mod/2 with negative
arguments?

Cheers --- Jan

rupert...@googlemail.com

unread,
Apr 15, 2008, 5:48:39 AM4/15/08
to

There is a helpful article on modulus and remainder here:

http://mindprod.com/jgloss/modulus.html

This relates to Java and its truncated (same as most hardware?)
division. The difference between modulus and remainder on negative
values as explained there, would seem to me to be the most obvious
differentiation between the intended behavior of mod and rem in
Prolog. That is, rem should be a fast remainder from a truncated
hardware division, and mod needs some sign adjusting afterwards to be
more mathematically correct. rem and mod should only differ when
negative operands are involved.

Rupert

Jan Wielemaker

unread,
Apr 15, 2008, 6:21:54 AM4/15/08
to

Thanks. At least that clarifies the rational. Doesn't really encourage
me to use any of this with negative operants as long as I can easily avoid
that :-)

--- Jan

Neng-Fa Zhou

unread,
Apr 15, 2008, 10:42:54 AM4/15/08
to

"Mats Carlsson" <ma...@sics.se> wrote in message
news:85ededd0-ab7f-4c43...@b64g2000hsa.googlegroups.com...

> On Apr 15, 2:33 am, Joachim Schimpf <jschi...@cisco.com> wrote:

> I disagree. The rules given in Section 9.1.3 of ISO/IEC 13211-1 seem
> unambiguous to me, namely if Y=\=0 then:
>
> mod(X,Y) = X-((X div Y)*Y)
> rem(X,Y) = X-((X // Y)*Y)
>
> where:
>
>> X // Y division with truncated result
>> X div Y division with floored result

Thanks for your clarification. I couldn't find these definitions in the
standard (the red-covered book). Now I hope more Prolog systems will be
consistent on these two functions.

Cheers,
Neng-Fa


Ulrich Neumerkel

unread,
Apr 16, 2008, 6:02:31 AM4/16/08
to
"Neng-Fa Zhou" <nz...@acm.org> writes:

> I couldn't find these definitions in the
>standard (the red-covered book). Now I hope more Prolog systems will be
>consistent on these two functions.

You may want examine the material accompanied with the compliance
tests conducted by Peter Szabo and Peter Szeredi in the course of
making SICStus compliant.

http://www.inf.bme.hu/~pts/stdprolog/

Maybe this test could be repeated? For one, SWI has improved quite a lot.
Also, the tests have been repeated for SICStus 4 beta. It would be even
nicer to announce those tests in advance.

0 new messages