sawa
sawa

Reputation: 168071

Is there a language that defines remainder modulo zero to equal the dividend? Why is it not common to define it that way?

Consider integer division:

a = bq + r

where a, b, q, r are respectively: dividend, divisor, quotient, and remainder. Particularly when b = 0, there is no unique q that satisfies the equation for a given a, and hence it makes sense that the quotient q should be undefined in such case.

However, there is indeed a unique r in such case, namely, r = a. Under the premise that the quotient and the remainder are always defined together, it would follow that r is not defined whenever q is undefined, but in programming, we often want to use the remainder operation % irrespective of division /. I actually came across a situation where I want if b == 0 then a else a % b end.

Is there/Was there an operator in any programming language such that it is the same as % but returns the dividend instead of a zero division error when the divisor is 0?

Is there any reason that most (or all) programming languages return a zero division error for % 0?

Upvotes: 7

Views: 6907

Answers (3)

dumbass
dumbass

Reputation: 27211

I know of three sources defining remainder of integer division such that it agree with your observation:

  • Donald Knuth in The Art of Computer Programming, Volume 1 (1969) (§1.2.4, p. 38) defines x mod 0 to equal x. For non-zero divisors it is defined as the remainder of flooring division: a mod b := ab × ⌊a ÷ b⌋. This definition is repeated in Concrete Mathematics by Knuth, Ronald Graham and Oren Patashnik.
  • The APL\1130 manual (also 1969) (p. 57) defines an operation | named “residue”, for non-zero divisors defined consistently with what Raymond Boute’s paper on defining integer division calls the “E-definition”, while for the zero divisor it returns the dividend, but only if the latter is non-negative; it is a domain error otherwise. It appears that the underlying mathematical definition of “residue” in APL\1130 is “smallest non-negative value that, when subtracted from the dividend, results in a multiple of the divisor”.
  • In the RISC-V instruction set, the “M” extension (RISC-V Instruction Set Manual, Volume I, Version 20191213, §7.2, p. 45, table 7.1) defines the remainder instructions to return the dividend in case of division by zero; the corresponding division instructions return the value with all bits set to 1 (which denotes −1 for signed division and the largest possible word value for unsigned division).

A naïve implementation of the unsigned long division algorithm will also agree with the RISC-V definition of division and remainder, assuming the remainder can be represented in the destination variable (and all intermediaries) without overflow.

Why is it not more common to define remainder modulo zero this way? I’d say it has more to do with practical, rather than mathematical, considerations. Remainder is commonly thought of as a by-product of division rather than a ring homomorphism in its own right; both operations are also usually implemented with a common instruction that computes both results. Since division by zero is undefined, many architectures choose it to trap (trigger an exception) in this situation, including the popular x86. Which means the remainder operation is going to trap as well. Languages at a higher level are rarely willing to override this choice, for a number of possible reasons:

  • not considering the issue at all, since situations in which remainder-by-zero legitimately appears are rare and raising an exception seems at first glance a reasonable choice;
  • reluctance to burden language implementations with divisor checks, which can hurt performance;
  • reluctance to diverge from other programming languages, where remainder modulo zero behaves similarly.

Upvotes: 0

riwalk
riwalk

Reputation: 14233

Is there any programming language that returns the dividend? Not sure. I've never come across any.

Is there a reason that most don't return the dividend? Yes. Modulus is a common operation in CS because it is a byproduct of integer division on a CPU. Most (if not all) assembly languages have a modulus operation, and this operation uses the exact same hardware as the division operation. Thus if you can't divide by zero in hardware, then you can't do modulus zero in hardware.

Does this mean that you can't have a language that supports this? Not really, but you would have to add an if-statement to an operation that is usually a single instruction. This would probably result in a pretty heavy performance hit, so few (if any) do it.

Upvotes: 2

pjwilliams
pjwilliams

Reputation: 288

Mathematically, the remainder is between 0 and b-1, where b is the divisor. Therefore, when b = 0, r is undefined since it has to be >= 0.

Upvotes: 2

Related Questions