Im Knuth (The Art of Computer Programming Vol. 1) ist die Modulo Operation so definiert:
[img]
http://mokrates.de/cgi-bin/texstring?%5C%5B%20x%20%5Cbmod%20y%20=%20%5Cleft%5C%7B%5Cbegin%7Barray%7D%7Br@%7B%5Cquad:%5Cquad%7Dl%7D%20x-y%5Clfloor%5Cfrac%7Bx%7D%7By%7D%5Crfloor%20&%20y%5Cnot=%200%20%5C%5C%20x%20&%20y=0%20%5Cend%7Barray%7D%20%5Cright.%20%5C%5D[/img]
Bei negativem x ist also z.B.
-2 mod 3 = 1
In Java kommt mit dem %-Operator aber -2 raus (in C uebrigens auch). Ich habe aber nirgendwo eine Definition vom Modulo Operator in Java (und in C) gefunden. Ueberall steht nur das es den Rest zurueck gibt.
Offensichtilch scheint es unterschiedliche Definitionen fuer den Rest zu geben. Was jemand mehr darueber?
BTW: In Perl und Python haehlt sich der %-Operator an die Definition vom Knuth.
/jr
EDIT: Definition verbessert
Das ist durchaus genau definiert:
Java Language Spec §15.17.3:
15.17.3 Remainder Operator %
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.
In C and C++, the remainder operator accepts only integral operands, but in the Java programming language, it also accepts floating-point operands.
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. This identity holds even in the special case that the dividend is the negative integer of largest possible magnitude for its type and the divisor is -1 (the remainder is 0). It follows from this rule that the result of the remainder operation can be negative only if the dividend is negative, and can be positive only if the dividend is positive; moreover, the magnitude of the result is always less than the magnitude of the divisor. If the value of the divisor for an integer remainder operator is 0, then an ArithmeticException is thrown.Examples:
5%3 produces 2 (note that 5/3 produces 1)
5%(-3) produces 2 (note that 5/(-3) produces -1)
(-5)%3 produces -2 (note that (-5)/3 produces -1)
(-5)%(-3) produces -2 (note that (-5)/(-3) produces 1)
http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#24956
Es handelt sich nicht um unterschiedliche Definitionen. 1 mod 3 ist nämlich äquivalent zu -2 mod 3. Also stimmen beide Ergebnisse. Was bei der Rechnung herauskommt, hängt also von der Implementation von modulo ab.
Es handelt sich nicht um unterschiedliche Definitionen. 1 mod 3 ist nämlich äquivalent zu -2 mod 3. Also stimmen beide Ergebnisse. Was bei der Rechnung herauskommt, hängt also von der Implementation von modulo ab.
Zur Definition kann durchaus gehören, welches äquivalente Element man nimmt [img]
http://www.fb18.de/gfx/28.gif[/img]
Zur Definition kann durchaus gehören, welches äquivalente Element man nimmt [img]http://www.fb18.de/gfx/28.gif[/img]
Aus genau dem Grund mache ich vorher immer eine Fallunterscheidung für jeden Operanden, der negativ sein könnte. Ich will mich einfach auf nichts verlassen.
Zur Definition kann durchaus gehören, welches äquivalente Element man nimmt [img]http://www.fb18.de/gfx/28.gif[/img]
ACK.
Hinweis: Im folgenden ist "/" immer die
Ganzzahldivision.
Wenn man die Gleichung (a/b)*b+(a%b) aufrechterhalten will (und das tun vermutlich alle genannten Sprachen), dann ergibt sich die Wahl des Elements auch daraus, wie bei der Ganzzahldivision gerundet wird.
AFAIK wird in Java immer zu 0 hin gerundet, bei Knuth wohl immer abgerundet. Also:
-16 / 3 = -6 (Knuth)
-16 / 3 = -5 (Java)
Die Variante von Java hat den Vorteil, daß
-a / b = -( a / b)
gilt. Wie man schön am obigen Beispiel sehen kann:
-16 / 3 = -( 16 / 3) = 5
Das ist durchaus genau definiert:
Java Language Spec §15.17.3:
15.17.3 Remainder Operator %
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.
In C and C++, the remainder operator accepts only integral operands, but in the Java programming language, it also accepts floating-point operands.
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. This identity holds even in the special case that the dividend is the negative integer of largest possible magnitude for its type and the divisor is -1 (the remainder is 0). It follows from this rule that the result of the remainder operation can be negative only if the dividend is negative, and can be positive only if the dividend is positive; moreover, the magnitude of the result is always less than the magnitude of the divisor. If the value of the divisor for an integer remainder operator is 0, then an ArithmeticException is thrown.Examples:
5%3 produces 2 (note that 5/3 produces 1)
5%(-3) produces 2 (note that 5/(-3) produces -1)
(-5)%3 produces -2 (note that (-5)/3 produces -1)
(-5)%(-3) produces -2 (note that (-5)/(-3) produces 1)
http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#24956
Thx, sowas hatte ich gesucht.
Ich hatte es unter google nur mit
modulo site:java.sun.com
versucht und nichts gefunden (vergesse immer URL zur Spec)…
*bookmark*
/jr
Also bleibt mir wohl nur sowas?
x == 0 ? x : x-y*((int) Math.floor(((double) x)/ y));
/jr
Wie waers mit:
x % y + (x >= 0 ? 0 : y)
Wie waers mit:
x % y + (x >= 0 ? 0 : y)
Danke, das sieht deutlich eleganter aus.
/jr