5

I'm not asking about the definition but rather why the language creators chose to define modulus with asymmetric behavior in C++. (I think Java too)

Suppose I want to find the least number greater than or equal to n that is divisible by f.

If n is positive, then I do:

if(n % f)
   ans = n + f - n % f;

If n is negative:

ans = n - n % f;

Clearly, this definition is not the most expedient when dealing with negative and positive numbers. So why was it defined like this? In what case does it yield expediency?

Maxpm
  • 24,113
  • 33
  • 111
  • 170
Ted Tool
  • 51
  • 1

2 Answers2

1

Because it's using "modulo 2 arithmetic", where each binary digit is treated independently of the other. Look at the example on "division" here

paulsm4
  • 114,292
  • 17
  • 138
  • 190
1

You're mistaken. When n is negative, C++ allows the result of the modulus operator to be either negative or positive as long as the results from % and / are consistent, so for any given a and b, the expression (a/b)*b + a%b will always yield a. C99 requires that the result of a % b will have the same sign as a. Some other languages (e.g., Python) require that the sign of a % b have the same sign as b.

This means the expression you've given for negative n is not actually required to work in C++. When/if n%f yields a positive number (even though n is negative), it will give ans that's less than n.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • `(a/b)*b + a%b` always yields `a` except if `b` is zero, then the behavior is undefined. – JohnPS Sep 17 '11 at 05:44
  • 1
    *"When n is negative, ...*" Better said, the result is implementation defined in C++03 if either the dividend or divisor is negative. However, most C++ compilers follow the C99 convention; this lets the vendor use the same machinery for C and C++ code. C++11 follows the C99 convention. It is no longer implementation defined. – David Hammen Sep 17 '11 at 09:51
  • @David: I considered pointing out that *either* operand being negative led to implementation defined results -- but since he'd talked specifically about `n` being negative, decided it was better discuss only that. As far as the similarity goes, C99 is more the follower than the leader -- i.e., they standardized it because essentially all modern hardware works that way. Microsoft, for one example, seems to use what the x86 `div` instruction produces, and shows no apparent interest in C99 conformance. – Jerry Coffin Sep 17 '11 at 20:25
  • I wonder how often the standards-mandated behavior is more useful than would be "If either operand to the integral divide or modulus operator is negative, the result shall be unspecified"? Such a spec would speed up implementations on processors which lack a signed-divide instruction [common in the world of embedded-systems]. I guess in situations where exactness doesn't really matter specifying that the quotient will be less than a unit away from the rational number defined by the division may be better than e.g. performing the divide as unsigned, but I wish there were a nice way... – supercat Jun 19 '13 at 21:49
  • ...to request proper modulus and round-to-negative division operations. – supercat Jun 19 '13 at 21:50
  • Incidentally, if `i` is a signed integer, computations like `i/16` and `i%16` could be performed faster using round-to-negative-infinity semantics on the division than using the standards-mandated semantics. – supercat Jun 19 '13 at 21:59