# danwinslow

Members

2,846

## Blog Comments posted by danwinslow

1. ### In Search of the True Modulus (an epic)

With Text_Io;

Procedure Foo is

A : Integer := -2;

B : Integer := 5;

Begin

Text_Io.WriteLine(Integer'Image(A mod B));

End;

Similarly, in Ada there are two different operators, "mod" (modulus)

and "rem" (remainder). Here's an explanation with plenty of detail:

Ada '83 Language Reference Manual - U.S. Government

Integer division and remainder are defined by the relation

A = (A/B)*B + (A rem B)

where (A rem B) has the sign of A and an absolute value less than

the absolute value of B. Integer division satisfies the identity

(-A)/B = -(A/B) = A/(-B)

The result of the modulus operation is such that (A mod B) has the

sign of B and an absolute value less than the absolute value of B;

in addition, for some integer value N, this result must satisfy

the relation

A = B*N + (A mod B)

...

For positive A and B, A/B is the quotient and A rem B is the

remainder when A is divided by B. The following relations are

satisfied by the rem operator:

A rem (-B) = A rem B

(-A) rem B = -(A rem B)

For any integer K, the following identity holds:

A mod B = (A + K*B) mod B

The relations between integer division, remainder, and modulus are

illustrated by the following table:

A B A/B A rem B A mod B A B A/B A rem B A mod B

10 5 2 0 0 -10 5 -2 0 0

11 5 2 1 1 -11 5 -2 -1 4

12 5 2 2 2 -12 5 -2 -2 3

13 5 2 3 3 -13 5 -2 -3 2

14 5 2 4 4 -14 5 -2 -4 1

10 -5 -2 0 0 -10 -5 2 0 0

11 -5 -2 1 -4 -11 -5 2 -1 -1

12 -5 -2 2 -3 -12 -5 2 -2 -2

13 -5 -2 3 -2 -13 -5 2 -3 -3

14 -5 -2 4 -1 -14 -5 2 -4 -4

So what's the conclusion? There are basically two models, reasonably

distinguished in Ada terms as Remainder and Mod; the C++ "%" operator

is really Remainder, not Mod, despite what it's often called.

Actually, its behavior for negative numbers is not even defined

officially; like many things in C, it's left to be processor-dependent

because C does not define how a processor should handle integer

division. Just by chance, all compilers I know truncate integers

toward zero, and therefore treat "%" as remainder, following the

precedent of FORTRAN. As _C: A Reference Manual_, by Harbison and

Steele, says, "For maximum portability, programs should therefore

avoid depending on the behavior of the remainder operator when

applied to negative integral operands."

×
×
• Create New...