| Die Modulo-(Rest)-Funktion beschreibt in der meist verwendeten Form den Rest einer ganzzahligen Division. | Die Funktion ist allerdings nicht eindeutig definiert. Es gibt mehrere Varianten, und man kann bei Bedarf eigene Varianten ergänzen. |
Algorithmen
|
Ausgewählte IT-Rezepte (Ganze Zahlen) |
| Modulo | Rest der ganzzahligen Division |
| Kalkulation | Asymmetrische Funktion REST() |
| Basic | Operator Mod für symmetrische Funktion |
| Javascript | Operator % für symmetrische Funktion |
| C/C++ | Operator % für symmetrische Funktion |
| Perl | Operator % für asymmetrische Funktion |
| PHP | Operator % für symmetrische Funktion |
| XSL | Operator mod |
| Verwandte Themen | Ganze Zahlen, Abschneiden (ceil(), Floor(), int() ) und Runden (round() ) von Gleitkomma-Zahlen zu ganzen Zahlen |
Modulo: Rest der ganzzahligen Division |
|||||||||||||||||||||||||
|
|||||||||||||||||||||||||
|
Für positive ganze Zahlen arbeitet die Modulo-(Rest)-Funktion
in allen Anwendungen gleich. Algorithmus für positive ganze Zahlen:
•
Man dividiert die beiden Argumente (n, m)
k = n / m
• und schneidet die Nachkomma-Stellen ab
k = floor(k)
• Danach bestimmt man den Rest
rest = n - k*m
♦ Details zu den Abschneide-Funktionen ceil(), floor(), int() |
Live-Demonstration der Modulo-Funktion
|
||||||||||||||||||||||||
RingzählerWenn man das 1.Argument (hier n) in einer Schleife schrittweise vergrößert, dann verhält sich die Modulo-Funktion wie ein Ringzähler: Sie liefert immer wieder das gleiche Zahlem-Muster, z.B. 0 1 2 0 1 2 ... |
Eine typische Anwendung ist die Berechnung der Wochentage: Sie folgen immer dem gleichen Ringzähler ( 0 1 2 3 4 5 6 0 1 2 ... ), auch über die Grenzen von Monaten oder Jahren hinweg. |
||||||||||||||||||||||||
Negative ZahlenFür negative ganze Zahlen <0 sind zwei verschiedene Algorithmen in Gebrauch, die sie in der Live-Demonstration umschalten können (Symmetrisch, Asymmetrisch). |
Die meisten Programmiersprachen verwenden den (zum Nullpunkt)
'symmetrischen' Algorithmus, der auch negative Resultate liefert. Alle ↓ Kalkulations-Programme und die Programmiersprache ↓ Perl verwenden den 'asymmetrischen' Algorithmus, der nur positive Zahlen erzeugt. |
||||||||||||||||||||||||
Gleitkomma-ZahlenUnabhängig von den Angeboten der Programmiersprachen kann es notwendig sein, die Modulo-Funktion auch mit negativen und/oder Gleitkomma-Argumenten zu berechnen.Die hier vorgestellten Gleitkomma (Double Precision) Funktionen werden zur Unterscheidung mit Namen ähnlich mod_dsym(), mod_dasym() bezeichnet. |
Für negative und/oder Gleitkomma-Argumente gibt es offenbar keine eindeutigen Algorithmen.
•
Die hier vorgestellten Funktionen stellen daher ausdrücklich keinen Anspruch
auf 'Richtigkeit'.
• Die Anwendung erfolgt auf eigenes Risiko ! |
||||||||||||||||||||||||
Symmetrische Modulo-Funktion• Der Algorithmus wird in allen 'symmetrischen' Beispielen dieser Seite verwendet und beschreibt das typische Verhalten der Modulo-Funktionen und -Operatoren in den meisten Programmiersprachen.• Er lässt sich auf alle hier vorgestellten Varianten anwenden, d.h. ganze und Gleitkomma-Zahlen, positive und negative Zahlen.
k = abs(n) / m
Auf dieser Seite werden dazu Beispiele mit Funktions-Namen
ähnlich mod_sym() vorgestellt.
k = floor(k) r = abs(n) - k * m if (n < 0) {r = -r} mod_sym(n,m) = r |
Asymmetrische Modulo-Funktion• Der Algorithmus wird in allen 'asymmetrischen' Beispielen dieser Seite verwendet und beschreibt das typische Verhalten der Funktionen gängiger Kalkulations-Programme und der Programmiersprache Perl.• Er lässt sich auf alle hier vorgestellten Varianten anwenden, d.h. ganze und Gleitkomma-Zahlen, positive und negative Zahlen.
k = n / m
Auf dieser Seite werden dazu Beispiele mit Funktions-Namen
ähnlich mod_asym() vorgestellt.
k = floor(k) r = n - k * m mod_asym(n,m) = r |
||||||||||||||||||||||||
|
Die hier verwendeten symbolischen Funktions-Namen bedeuten abs ... Absolut-Wert floor ... Abschneide-Funktion (♦ Details) |
Je nach den Möglichkeiten der einzelnen Programmiersprache lassen sich die beiden Varianten des Algorithmus vereinfachen. | ||||||||||||||||||||||||
Rechen-RegelnMan findet in der Literatur und im Internet mehrere Regeln zum Verhalten der Modulo-Funktion bei Umformung.• Die meisten gelten nur für einen der beiden Algorithmen und/oder nur für spezielle Bedingungen (ganze Zahlen, positive Zahlen) - leider meist ohne dass die jeweiligen Bedingungen genannt werden. |
♣ Tipp: Trauen sie keiner der publizierten Regeln ohne praktische Kontrolle. • Die einzige Regel, die sich in Versuchen als haltbar erwiesen hat: mod(-n,-m) = -mod(n,m)
(Vertrauen sie auch dieser Regel nicht ohne Test !)
|
||||||||||||||||||||||||
Funktion REST() mit Kalkulations-Programmen |
|||||||||||||||||||||||||||||||||||
Funktion REST()Alle Standard Kalkulations-Programme (LibreOffice-Calc, MS-Excel, ...) bieten diese Funktion.Das Beispiel demonstriert in Spalte B die 'asymmetrische' Funktion REST(), in Spalte C die 'symmetrische' Variante der Modulo-Funktion. Für n>=0 ergeben beide Varianten das gleiche Resultat. |
|||||||||||||||||||||||||||||||||||
| ● Man muss jede Formel nur einmal eintragen. Sie können die Zellen A4:A16 sowie B3:C16 nach unten ausfüllen, und natürlich auch weiter nach unten verlängern. |
•
Das 1.Argument der Modulo-Funktionen (Dividend n)
wird aus Spalte A entnommen, das 2.Argument
(Divisor m) aus Zelle B1. • Ändern sie die Zahl in B1, um einen anderen (kürzeren, längeren) Ringzähler zu berechnen. |
||||||||||||||||||||||||||||||||||
Gleitkomma-ZahlenDie Funktion REST() lässt sich auch auf Gleitkomma-Zahlen anwenden.Die/der AnwenderIn ist dafür verantwortlich, ob das auch sinnvoll ist. Beide Argumente können auch Gleitkomma-Zahlen sein und werden dem gleichen ↑ Algorithmus unterworfen wie oben gezeigt. |
Ersatz-FormelDie Funktion REST() lässt sich durch eine Formel ersetzen. Das hat keinen praktischen Wert, ist jedoch für EntwicklerInnen eine Aufgabe zur Umsetzung eines einfachen Algorithmus:REST(n,m) = n-m*GANZZAHL(n/m)
Alternativ können sie auch jede der 'Benutzer-definierten'
↓ Basic-Funktionen verwenden.
|
||||||||||||||||||||||||||||||||||
Modulo mit Basic (LibreOffice-Basic, Visual Basic VBA) |
|
|
Ein Interpreter für diese Programmiersprache ist in jedem Standard
Kalkulations-Programm (LibreOffice-Calc,
MS-Excel, ...) enthalten. Da auf den meisten Arbeits-PC mit einem Office-Paket auch ein Kalkulations-Programm installiert ist, kann man Basic einfach und ohne zusätzliche Programme verwenden. |
Basic-Funktionen sind portabel, d.h. man kann den Quelltext der Funktionen ohne Änderung in einem → Basic-Modul jedes Standard Kalkulations-Programm verwenden. |
Operator ModBasic verwendet den Operator Mod an Stelle einer Funktion:Das Wort Mod wird genauso verwendet wie andere Operatoren (+ - * / usw.) Der Operator arbeitet symmetrisch zum Nullpunkt, so wie im ↑ Live-Beispiel gezeigt. Der Operator funktioniert nur mit ganzzahligen Argumenten bis n<=(2^31)-1 Man kann die Funktion in einem Kalkulations-Programm als Benutzer-definierte Funktion verwenden, z.B. im Bereich C3:C16 des im Kapitel ↑ Kalkulation gezeigten Beispiels. |
Symmetrische Basic Funktion mod_sym() für ganze Zahlen
Function mod_sym(n As Integer, m As Integer) As Integer
Dim k As Integer
k = n Mod m
End Function
mod_sym = k |
Symmetrische Gleitkomma-FunktionDas Beispiel zeigt zwei Varianten der Modulo-Funktion für Gleitkomma-Zahlen, die symmetrisch zum Nullpunkt arbeitet.Man kann sie sowohl Basic-intern als auch in einem Kalkulations-Programm als Benutzer-definierte Funktion verwenden. • Die erste Version mod_dsym_1() folgt genau dem oben vorgestellten ↑ Algorithmus. • Die zweite Version mod_dsym_2() nutzt die von Basic gebotenen Möglichkeiten zur Vereinfachung. • In beiden Beispielen werden die Variablen-Typen Integer, Double automatisch ineinander umgewandelt. Das funktioniert in Basic, ist jedoch allgemein nicht empfehlenswert und in 'strengen' Programmiersprachen (↓ C/C++) nur mit ausdrücklichen Anweisungen möglich. |
Basic
Funktion mod_dsym() für Gleitkomma-Zahlen:
Function mod_dsym_1(n As Double, m As Double0) As Double
Alternative Version der gleichen Funktion:
Dim k, r As Double
k = Int(Abs(n) / m)
End Function
r = Abs(n) - k * m If (n < 0) Then r = -r mod_dsym_1 = r
Function mod_dsym_2(n As Double, m As Double) As Double
Dim k, r As Double
k = Fix(n / m)
End Function
r = n - k * m mod_dsym_2 = r |
Asymmetrische Varianten der Modulo-FunktionDiese Funktion zeigt sowohl für ganze Zahlen (mod_asym() ) als auch in der Version für Gleitkomma-Zahlen (mod_dasym() ) das gleiche Verhalten wie die ↑ Kalkulations-Funktion REST().Sie ist daher nur für Basic-interne Anwendung sinnvoll, z.B.
w1 = mod_asym(12345,7)
w2 = mod_dasym(123.456,7.89) ♣ Verwenden sie nach Möglichkeit immer ganze Zahlen: Damit rechnet man innerhalb des Werte-Bereichs immer exakt. Gleitkomma-Zahlen haben einen weit größeren Werte-Bereich, aber eine auf ca. 16 Dezimal-Stellen begrenzte → Genauigkeit. |
Basic
Funktion mod_asym() für ganze Zahlen:
Function mod_asym(n As Integer, m As Integer) As Integer
Dim k As Integer
k = n Mod m
End Function
If k < 0 Then k = k + m mod_asym = k Basic Funktion mod_dasym() für Gleitkomma-Zahlen:
Function mod_dasym(n As Double, m As Double) As Double
Dim k, r As Double
k = Int(n / m)
End Function
r = n - k * m mod_dasym = r |
Modulo mit Javascript |
|
|
Ein Interpreter für diese Programmiersprache ist in jedem gängigen
Browser-Programm enthalten. Daher kann man Javascript einfach und ohne zusätzliche Programme verwenden. |
Javascript-Programme sind im Quelltext einer Webseite enthalten und zusammen mit der Webseite portabel: Sie funktionieren ohne Änderung auf jedem Betriebssystem und mit jedem gängigen Browser. |
Operator %Javascript verwendet den Operator % an Stelle einer Funktion.Der Operator arbeitet symmetrisch zum Nullpunkt, so wie im ↑ Live-Beispiel mit der Option 'Programmierung' gezeigt. Der Operator funktioniert mit beliebigen Zahlen: Ganzzahlig oder Gleitkomma, positiv oder negativ. |
Javascript Funktion mod_sym()
function mod_sym(n,m) {
Die Funktion ist in dieser Form sinnlos, sie demonstriert lediglich
die einfache Anwendung des % Operators.
return n % m;
}
|
Asymmetrische FunktionDiese Funktion zeigt sowohl für ganze Zahlen (mod_asym() ) als auch in der Version für Gleitkomma-Zahlen (mod_dasym() ) das gleiche Verhalten wie die ↑ Kalkulations-Funktion REST(). |
Javascript
Funktion mod_asym()
function mod_asym(n,m) {
var k = Math.floor(n/m);
}
var r = n - k * m; return r; |
Live-DemonstrationMit Klick auf den Button wird ein Dialog-Fenster geöffnet. Sie können die Argumente n und m eingeben und beide Varianten der Modulo-Funktion Live mit Javascript berechnen. |
Live Berechnung beider Versionen der Modulo-Funktion mit Javascript. |
Modulo mit C/C++ |
|
| Man braucht ein → Compiler-Programm zur Übersetzung von C/C++ Quelltext in ein 'Ausführbares Programm' (z.B. auf Windows *.exe). | Der Quelltext der Programmiersprache(n) → C/C++ ist portabel, die damit erzeugten Programme sind jedoch nicht portabel. Man muss für jedes Betriebssystem, teilweise auch für Betriebssystem-Varianten eigene Programme herstellen. |
Operator %C/C++ verwendet den Operator % an Stelle einer Funktion.• Der Operator arbeitet symmetrisch zum Nullpunkt, so wie im ↑ Live-Beispiel mit der Option 'Programmierung' gezeigt. • Der Operator funktioniert nur mit ganzen Zahlen. Das Beispiel zeigt ein C-Programm, welches die beiden ganzzahligen Funktionen demonstriert: • Der Wert des 1. Arguments n wird in einer Schleife (hier von -3 bis +10 durchlaufen). • Der Wert des 2. Arguments m ist im Programm vorgegeben (hier m=3) Beide Funktionen mod_sym() und mod_asym() verwenden den Modulo-Operator % zur Berechnung. Die Funktion mod_sym() ist in dieser Form überflüssig, weil man an ihrer Stelle direkt den Operator % verwenden kann. Sie wird hier angeführt, damit sie mit den Beispielen anderer Programmiersprachen vergleichbar ist. |
C/C++ Programm
zur Demonstration verschiedener ganzzahliger Modulo-Funktionen:
#include <stdio.h>
int mod_sym(int,int); int mod_asym(int,int); int main() {
int ir,m,n;
}m = 3; for(n=-3;n<=10;n++) {
printf("mod(%d,%d):",n,m);
}ir = mod_sym(n,m); printf(" sym=%d",ir); ir = mod_asym(n,m); printf(" asym=%d\n",ir); return 0; int mod_sym(int n,int m) {
int k;
}k = n % m; return k; int mod_asym(int n,int m) {
int k;
}k = n % m; if(k<0) {k+=m;} return k; |
|
Dieses Beispiel zeigt ein C-Programm, welches die beiden Varianten
der Gleitkomma-Funktionen demonstriert. • Das Programm ist genau analog aufgebaut wie das Programm für ganzzahlige Modulo-Funktionen im vorigen ↑ Absatz. • Die Namen der Variablen sind so gewählt, dass man die beiden Programme zu einem einzigen Programm zusammenlegen kann, welches alle 4 Varianten der Funktion demonstriert. • Der Wert des 1. Arguments rn wird in einer Schleife (hier von -3.0 bis 3.0 durchlaufen). • Der Wert des 2. Arguments rm ist im Programm vorgegeben (hier rm=3.0) • Die Funktionen mod_dsym() und mod_dasym() verwenden den oben angeführten ↑ Algorithmus zur Berechnung, weil der Modulo-Operator % nur für ganze Zahlen verwendbar ist. Die → Abschneide-Funktion floor() ist in der Bibliothek <math.h> enthalten, die man zusätzlich einbinden muss. • Die Absolutwert-Funktion abs() ist in C nur für ganze Zahlen verwendbar und wird daher als Hilfs-Funktion dabs() ergänzt. In C++ ist die Funktion abs() überladen und kann auch für Gleitkomma-Typen verwendet werden. |
C/C++ Programm
zur Demonstration verschiedener Gleitkomma Modulo-Funktionen:
#include <stdio.h>
#include <math.h> double mod_dsym(double,double); double mod_dasym(double,double); double dabs(double); int main() {
double drn,r,rm,rn;
}rm = 3.0; rn = -3.0; drn = 0.5; while(rn<=3.0) {
printf("dmod(%f,%f):",rn,rm);
}r = mod_dsym(rn,rm); printf(" sym=%f",r); r = mod_dasym(rn,rm); printf(" asym=%f\n",r); rn += drn; return 0; double mod_dsym(double n,double m) {
double k,r;
}k = floor(dabs(n)/m); r = dabs(n) - k * m; if(n<0) {r=-r;} return r; double mod_dasym(double n,double m) {
double k,r;
}k = floor(n/m); r = n - k * m; return r; double dabs(double x) {
if(x>=0.0) {return x;}
}
else{return -x;} |
Modulo mit Perl |
|
| Der Quelltext von → Perl-Programmen wird in einfachen Text-Dateien (Script-Programmen *.pl) gespeichert und von einem Perl-Interpreter-Programm Live ausgeführt. | Man braucht daher ein (kostenfreies) Interpreter-Programm zur Ausführung eines (portablen) Perl-Script-Programms. |
Operator %Perl verwendet den Operator % an Stelle einer Funktion.• Der Operator arbeitet im Gegensatz zu den meisten anderen Programmiersprachen asymmetrisch zum Nullpunkt. • Er lässt sich nur auf ganze Zahlen zuverlässig anwenden. |
● Perl kann große ganze Zahlen ohne Warnung automatisch in den Gleitkomma-Typ umwandeln. In diesem Fall arbeiten die Ganzzahlen-Funktionen evtl. fehlerhaft. Verwenden sie in diesem Fall das → Perl-Modul Math::BigInt ! |
|
Das Perl-Programm demonstriert die beiden Varianten der Modulo-Funktionen: • Der Wert des 1. Arguments $n wird in einer Schleife (hier von -3 bis +10 durchlaufen). • Der Wert des 2. Arguments $m ist im Programm vorgegeben (hier $m=3) • Die Funktion mod_sym() folgt dem oben angegebenen ↑ Algorithmus. Die → Abschneide-Funktion int() arbeitet in Perl ebenfalls symmetrisch zum Nullpunkt. • Die Funktion mod_asym() verwendet den Modulo-Operator % zur Berechnung, ist jedoch nur auf ganzzahlige Argumente korrekt anwendbar. • Die Funktion mod_dasym() arbeitet auch mit Gleitkomma-Argumenten. Sie liefert als Sonderfall für ganzzahlige Argumente das gleiche Ergebnis wie der % Operator bzw. die Funktion mod_asym() |
Perl Programm
zur Demonstration verschiedener Gleitkomma Modulo-Funktionen: #!/usr/bin/perl
use strict;my($n,$m,$r); $m=3; for($n=-3;$n<=10;$n++) {
print "mod($n,$m):";
}$r = mod_sym($n,$m); print " sym=$r"; $r = mod_asym($n,$m); print " asym1=$r"; $r = mod_dasym($n,$m); print " asym2=$r\n"; sub mod_sym {
my($n,$m)=@_;
}my $k = int($n / $m); my $r = $n - $k * $m; return $r; sub mod_asym {
my($n,$m)=@_;
}return $n % $m; sub mod_dasym {
my($n,$m)=@_;
}
my $k = $n / $m; $k = my_floor($k); my $r = $n - $k * $m; if($r>=$m) {$r-=$m;} return $r; |
Modulo mit PHP |
|
| Der Quelltext von → PHP-Programmen wird in einfachen Text-Dateien (Script-Programmen *.php) gespeichert und von einem PHP-Interpreter-Programm Live ausgeführt. |
Man braucht daher ein (kostenfreies) Interpreter-Programm zur Ausführung
eines (portablen) PHP-Script-Programms. Mit PHP-Programmen werden meistens Webseiten hergestellt und von einem → Webserver-Programm verteilt. |
Operator %PHP verwendet den Operator % an Stelle einer Funktion.• Der Operator arbeitet symmetrisch, so wie im ↑ Live-Beispiel mit der Option 'Programmierung' gezeigt. • Er lässt sich nur auf ganze Zahlen zuverlässig anwenden. |
● PHP kann große ganze Zahlen ohne Warnung automatisch in den Gleitkomma-Typ umwandeln. In diesem Fall arbeiten die Ganzzahlen-Funktionen evtl. fehlerhaft. Verwenden sie in diesem Fall eines der beiden → PHP-Module BC-Math oder GMP ! |
|
Das Beispiel zeigt PHP-Funktionen zur Berechnung der Modulo-Funktion,
mit Demonstration der Anwendung auf einer dynamischen Webseite. Anwendung:
•
So wie in den anderen Beispielen dieser Seite wird das 1.Argument
(hier $n) in einer Schleife schrittweise von
-3 bis +10 erhöht.• Das 2.Argument (hier $m) ist im Programm fix vorgegeben. Funktionen:
•
Die Funktion mod_sym() zeigt lediglich die Anwendung
des % Operators. Sie ist nur auf ganze Zahlen korrekt
anwendbar.• Die Funktion mod_dsym() berechnet die symmetrische Variante der Modulo-Funktion auch für negative und/oder Gleitkomma-Zahlen. Als Sonderfall liefert sie für ganzzahlige Argumente das gleiche Ergebnis wie der % Operator bzw. die Funktion mod_sym() • Die Funktion mod_asym() berechnet die asymmetrische Variante der Modulo-Funktion auch für negative und/oder Gleitkomma-Zahlen. |
Varianten der Modulo-Funktion mit PHP
<?php
$m = 3;for($n=-3;$n<=10;$n+=1) {
print "mod($n,$m):\n";
}$ r= mod_sym($n,$m); print " sym1=$r"; $r = mod_dsym($n,$m); print " sym2=$r"; $r = mod_asym($n,$m); print " asym=$r<br />\n "; function mod_sym($n,$m) { return $n % $m;
}function mod_dsym($n,$m) {
$k = abs($n) / $m;
}$k = floor($k); $r = abs($n) - $k * $m; if ($n < 0) {$r = -$r;} return $r; function mod_asym($n,$m) {
$k = $n / $m;
}
$k = floor($k); $r = $n - $k * $m; return $r; ?>
|
Modulo mit XPath und XSL |
|||
Operator modDer Operator mod arbeitet so wie in anderen Programmiersprachen.
|
Die Programmierung ist allerdings wegen der speziellen Eigenschaften von XSL anders als von anderen Programmsprachen gewohnt: Links: ► XML-Quelltext mit Rechtsklick in die Farben-Tabelle. ► XSL-Programm ► Live-Demo einiger → XML+XSL Beispiele |
||
Modulo mit der Linux-Shell |
|
Operator %Auch die 'Sprache' der Linux → Shell-Konsole bietet den Operator % zur Berechnung der Modulo-Funktion. |
# m = $n % $m
|