Ok, this isn't a question so much as a discovery. I often see "%" referred to as the "mod" operator, but it isn't really - it is more like a remainder operator, since it gives negative values for negative "dividends."

That's because % *is* defined in Java as the remainder: remainder = a - (a/b)*b If you don't want a negative mod, add the divisor to it when it is negative.

Apparently modulo is defined differently in different languages. In comparing Python with C++, for example, we see the following:

Java was, in many ways, modelled after C/C++ (to entice them to switch to Java).

JavaBeginnersFaq "Yesterday is history, tomorrow is a mystery, and today is a gift; that's why they call it the present." Eleanor Roosevelt

Jeff Albertson
Ranch Hand

Joined: Sep 16, 2005
Posts: 1780

posted

0

Quick, what's -1/2?

To summarize (I'm quoting the JSL, because I don't trust my memory:

"Integer division rounds towards 0." (�15.17.2) (So -1/2 is 0, not -1)

"The binary % operator is said to yield the remainder of its operands from an

implied division; the left-hand operand is the dividend and the right-hand operand is the divisor."

"The remainder operation for operands that are integers after binary numeric promotion (�5.6.2) produces a result value such that (a/b)*b+(a%b) is equal to a." (�15.17.3)

Adam Price
Ranch Hand

Joined: Nov 11, 2005
Posts: 95

posted

0

Originally posted by Stuart Goss: Sorry, I see no reason why the number theory modulo operator may not return negative values ...

Commonly, modulo is defined as the remainder in division, but that isn't the formal mathematical definition. In number theory, modulo is defined by the divisibiliy of the difference of two values:

a and b are equal modulo c if |a-b| is divisible by c So to find a mod c, convention has us find the smallest positive b that exists and satisfies the relationship.

-12 mod 10, for instance, asks us to fill in the blank: -12=b (mod x) =>|-12 - b| is divisible by 10, and as small as positively possible and 8, not -2 is the solution. A matter of definition, I suppose, and nothing more, but the convention in math clearly doesn't match the convention in Java.

Originally posted by Marilyn de Queiroz: Apparently modulo is defined differently in different languages. In comparing Python with C++, for example, we see the following:

Java was, in many ways, modelled after C/C++ (to entice them to switch to Java).

I can deal with the C/C++ convention, (and the Java one) but that python output is weird!

Originally posted by Jeff Albrechtsen: Quick, what's -1/2?

To summarize (I'm quoting the JSL, because I don't trust my memory:

"Integer division rounds towards 0." (�15.17.2) (So -1/2 is 0, not -1)

"The binary %

That's good to know.

Thanks for your thoughts, everyone.

-Adam

Adam Price
Ranch Hand

Joined: Nov 11, 2005
Posts: 95

posted

0

Originally posted by Adam Price:

Java was, in many ways, modelled after C/C++ (to entice them to switch to Java).<hr></blockquote>

I can deal with the C/C++ convention, (and the Java one) but that python output is weird!

That's good to know.

Thanks for your thoughts, everyone.

-Adam[/QB]

Ok - now that I look at it some more, I see that it actually does exactly what I would have expected, and it is still the c/++/java output that sticks out.

In terms of mathematical correctness, modular arithemetic is defined on a ring such that in the example -12 modulo 10, the class of numbers defined by -2 is congruent to the class of numbers defined by 8. Meaning on the ring 10, all arithmetic operations would be the same regardles of which number you chose, -2 or 8, for the operation

Java picks the least most positive number for the ring, which is also what you commonly use to represent that class of numbers in mathematics, ie, -12, -2, 8, 18, and 28 on ring 10 would be represented as {8}.

Originally posted by Scott Selikoff: In terms of mathematical correctness, modular arithemetic is defined on a ring such that in the example -12 modulo 10, the class of numbers defined by -12 is congruent to the class of numbers defined by 8. Meaning on the ring 10, all arithmetic operations would be the same regardles of which number you chose, -2 or 8, for the operation

Agreed

Java picks the leastmost positive number for the ring, which is also what you commonly use to represent that class of numbers in mathematics, ie, -12, -2, 8, 18, and 28 on ring 10 would be represented as {8}.

But that's just the problem - it doesn't. On ring 2, returns negative one for all negative odd . Unless you are talking about a different way to get the congruence class than [code[-12 mod 10[/code]. It truly is returning the remainder, not the least positive member of the congruence class

Originally posted by Adam Price: Unless you are talking about a different way to get the congruence class than [code[-12 mod 10[/code]. It truly is returning the remainder, not the least positive member of the congruence class

You're right, java always returns the remainder instead of modular arithmetic. For negative numbers, java returns the greatest negative congruent element, and for positive numbers, java returns the smallest positive congruent element.

Keep in mind that in math, they are the exact same thing. In ring algebra, the congruence of two numbers implies equivalence. Ergo, -2 is 8, and you could write it as {-2} or {8}. Its like saying 5 is 5, in that particular arithmetic although the numbers are different they represent the same object, ie they point to the same numeric absolute even though they are represented differently. For example, there's a long standing argument that 0.9999999 (with 9's to infinity) is the same as 1. Numbers represent objects that can often not be expressed exactly in the real world such as trying to express PI in finite terms (although you can make a good stab at it by expressing it as a sequence).

Math is often abstract, computers are not. There a tons of places where computers have to approximate things that in math you would not wish to do. If it was me, I probably would have coded % to return positive numbers such as the behavior of BigInteger.mod(), although I'm sure there's some old reason why it doesn't