Modulo mit negativen Zahlen

Rol

Aktives Mitglied
Hi,
ich möchte einen Ringspeicher adressieren. Der Speicherbesteht aus einem Array das z.B. 512 Elemente lang ist und hat einen Zeiger der am Anfang auf dem Element 0, also array[0], steht. Wird ein Element eingeschrieben wird danach der Zeiger inkremetiert, ist der Zeiger >= 512 wird er wieder auf 0 gesetzt. Soweit, so gut!
Ein Problem trit jetzt auf wenn z.B. der Zeiger auf 100 steht und ich das 101. Element _VOR_ dem Zeiger adressieren möchte. Um die Position im Array zu berechnen wollte ich es so machen:

array[zeiger+gewünschtesElemet % Arraylänge]
=
array[100 - (-101) % 512]
=
array[-1 % 512]. Das sollte eigentlich 511 ergeben, ergibt in Java(!) aber -1!

Nun könnte ich das zu Fuß mit If(...) und so machen aber die Operation wird in meiner Anwendung sehr oft (>>100.000.000) verwendet und soll deshalb sehr performant sein.

Gibt es in Java eigentlich gar keinen "richtigen" Modulo Operator?

Gruß
Rol
 

Ark

Top Contributor
Wenn dir Performance wirklich extremst wichtig ist, dann sieh zu, dass du nur mit Zweierpotenzen zu tun kriegst, denn so ein % dauert relativ lange (bei Zweierpotenzen kommt man mit & aus). Ansonsten: addiere einfach dann, wenn du in den negativen Bereich kommst, die Arraylänge hinzu:

Also so:
Java:
int i = (zeiger + gewünschtesElement) % Arraylänge;
if(i < 0) i += Arraylänge;
array[i] usw.

Wenn dir das dann immer noch zu langsam ist (weil du dich vllt. nicht auf Zweierpotenzen beschränken kannst), musst du versuchen, den Modulo-Operator komplett zu entfernen. Das geht aber nur mit eventuellen Einschränkungen und muss dann auch nicht immer performanter sein; ein Abwägen zur Laufzeit macht den Code aber vor allem unübersichtlich. Versuche also zunächst, an anderen Stellen schneller zu werden, wenn möglich. Um herauszufinden, wo sich das lohnt, gibt's Profiler.

Ark
 
Zuletzt bearbeitet:

0x7F800000

Top Contributor
naja, bei 512 ist's doch perfekt!

Hab's mal die 3 methoden schnell getestet:
Java:
public class ModProblems {

	// most general version
	static int mod(int a, int b){
		int res = a % b;
		return res < 0 ? res + b : res;
	}
	
	// if absolute value of a is limited by limit with limit = 0 mod b, this should work faster
	static int modLimited(int a, int b, int limit){
		return (a + limit) % b; 
	}
	
	// if b is a power of 2
	static int modPow2(int a, int bMinusOne){
		return a & bMinusOne;
	}
	
	public static void main(String... _){
		
		int b = 512;
		int bMinusOne = b - 1;
		int limit = 512*16;
		
		// visual test: all three results should be equal and between 0 and 512
		for (int i = 0; i < 20; i ++){
			int a = (int)(java.lang.Math.random()*1000 - 500);
			System.out.println(mod(a, b) + "\t" + modLimited(a, b, limit) + "\t" + modPow2(a, bMinusOne));
		}
		
		System.out.println("\n");
		
		// shitty benchmark
		int N = 500000000;
		{
			long tStart = System.currentTimeMillis();
			for (int i = 0; i < N; i++){
				mod(i-100, b);
			}
			System.out.println("mod:\t" + (System.currentTimeMillis() - tStart));
		}
		{
			long tStart = System.currentTimeMillis();
			for (int i = 0; i < N; i++){
				modLimited(i-100, b, limit);
			}
			System.out.println("lim:\t" + (System.currentTimeMillis() - tStart));
		}
		{
			long tStart = System.currentTimeMillis();
			for (int i = 0; i < N; i++){
				modPow2(i-100, bMinusOne);
			}
			System.out.println("pow:\t" + (System.currentTimeMillis() - tStart));
		}
	}
}
Ergebnis:
Code:
mod:	4806
lim:	3724
pow:	436
Also ist die allgemeine Version nur unwesentlich lahmer, als die Version, wo die Indizes betragsmäßig beschränkt sind, aber das mit bitwise-AND ist zehn mal schneller.
 

faetzminator

Gesperrter Benutzer
Oder einfach vor dem Modulo ganz ohne Kontrolle noch schnell den Wert hinzufügen - in Ark's Beispiel also [c]int i = (zeiger + gewünschtesElement + Arraylänge) % Arraylänge;[/c]
 

0x7F800000

Top Contributor
Oder einfach vor dem Modulo ganz ohne Kontrolle noch schnell den Wert hinzufügen - in Ark's Beispiel also [c]int i = (zeiger + gewünschtesElement + Arraylänge) % Arraylänge;[/c]
genau das tut modLimited, falls man sich darauf verlassen kann, dass Betrag von [c]zeiger + gewElem[/c] stets kleiner gleich [c]ArrayLänge[/c] ist. Wenn das so ist, dann sollte man es so machen, wenn die ArrayLänge keine Zweierpotenz ist.
 

Ark

Top Contributor
falls man sich darauf verlassen kann, dass Betrag von [c]zeiger + gewElem[/c] stets kleiner gleich [c]ArrayLänge[/c] ist.
Dies ist aber nur dann von Interesse, wenn der Ausdruck negativ ist, und dann kann man auch gleich zu einer simplen if-Abfrage greifen und % komplett entfernen.

Gerade wegen solcher Schwierigkeiten sollte man die Repräsentanten erst nach der Modulo-Rechnung auswählen.

Ark
 

0x7F800000

Top Contributor
Dies ist aber nur dann von Interesse, wenn der Ausdruck negativ ist, und dann kann man auch gleich zu einer simplen if-Abfrage greifen und % komplett entfernen.
Das stimmt. Aber im Unterschied zu einer einfachen if-Abfrage funktioniert es auch noch, wenn der Betrag kleiner gleich 2*ArrayLänge oder 10000*ArrayLänge ist. Da kommt man ohne % nicht weiter. Wie die obere Schranke aussieht, muss aber der Threadersteller selbst wissen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Modulo - double Allgemeine Java-Themen 21
P Best Practice Wieso funktioniert der Modulo - Operator nicht? Allgemeine Java-Themen 2
T Modulo-Operator versagt bei zu großen Zahlen? Allgemeine Java-Themen 14
A Was berechnet Modulo denn da? Allgemeine Java-Themen 5
C Brauche Hilfe mit Modulo Strategie Allgemeine Java-Themen 2
B "Verschlüsselung" mit Passwort (XOR bzw. Modulo) Allgemeine Java-Themen 7
hdi Wahrscheinlichkeitsfrage bei hashCode() mit modulo Allgemeine Java-Themen 7
P große double Zahlen und modulo Allgemeine Java-Themen 8
I Problem mit Modulo Allgemeine Java-Themen 14
D Erste Schritte Fehler mit negativen und 0 Zahlen im String Allgemeine Java-Themen 6
D Operatoren Logischer Rightshift von negativen Zahlen auf Bit-Ebene Allgemeine Java-Themen 7
berserkerdq2 Versteht jemand, was diese beiden Zahlen bei dem IJVM Code zu bedeuten haben? Allgemeine Java-Themen 10
L die 3 größten Zahlen im Array Allgemeine Java-Themen 1
A Potenzmenge der Zahlen von 1 bis n Allgemeine Java-Themen 20
Monokuma String List nach Zahlen und Worten sortieren Allgemeine Java-Themen 9
G Java Editor Löschen doppelter Zahlen einer Liste Allgemeine Java-Themen 2
A String auf Zahlen überprüfen Allgemeine Java-Themen 5
J Zahlen Abstand zur Null bestimmen Allgemeine Java-Themen 11
R Methoden Was fehlt mir bzw. muss ich bei der Methode countHarshabNumbers ändern damit ich die Harshad Zahlen im Intervall [51, 79] zählen kann? Allgemeine Java-Themen 19
O Variablen Addition von Double-Werten ergibt seltsame 0.9999999 Zahlen Allgemeine Java-Themen 2
B Zufällig zwischen vorgegebenen Zahlen auswählen Allgemeine Java-Themen 6
P Rechnen mit sehr kleinen Zahlen Allgemeine Java-Themen 5
M Zahlen in Array anordnen Allgemeine Java-Themen 8
D Erste Schritte Arrays vergleichen und die zahlen die nur einmal vorkommen ausgeben Allgemeine Java-Themen 5
T Tesseract OCR mit Zahlen Allgemeine Java-Themen 1
D Integer-Array variabler Größe mit Zahlen befüllen (Schleifen) Allgemeine Java-Themen 0
F Zahlen zu Bits Allgemeine Java-Themen 3
S Überprüfen, ob 5 Zahlen nebeneinander liegen Allgemeine Java-Themen 5
R Große Zahlen in Worten abkürzen Allgemeine Java-Themen 10
B Arrays mit Text und Zahlen füllen Allgemeine Java-Themen 3
G Aus JTextField Zahlen auslesen und random generieren Allgemeine Java-Themen 10
L 2-Dimensionaler String: Zahlen verschieben Allgemeine Java-Themen 10
M Algorithmus zum Zahlen einteilen Allgemeine Java-Themen 8
H Fibonacci-Zahlen Allgemeine Java-Themen 5
B Zahlen manuell eingeben und in Array Speichern Allgemeine Java-Themen 2
E mit extrem langen Zahlen (als Zeichneketten) arbeiten Allgemeine Java-Themen 4
M Probleme beim rechnen, bei Zahlen mit führenden Nullen. Allgemeine Java-Themen 7
L Filewriter schreibt Zahlen in Textdatei Allgemeine Java-Themen 2
T Methoden Zahlen austauschen Allgemeine Java-Themen 8
Z Zahlen aus Bild auslesen Allgemeine Java-Themen 1
M ungerade zahlen auf 4 zahlen aufteilen Allgemeine Java-Themen 2
F Funktionsplotter komplexe Zahlen: geeignetes 3D-Koordinatensystem Allgemeine Java-Themen 16
B Zahlen ausgeben hilfe! Allgemeine Java-Themen 8
S Zahlen aus (String mit zahlen) immer wieder neu auslesen Allgemeine Java-Themen 5
N Bin to Dez und umgekehrt mit sehr großen Zahlen Allgemeine Java-Themen 2
AssELAss String mit Zahlen mit Tausendertrennzeichen versehen Allgemeine Java-Themen 14
D Code bitte mit 19 stelligen Zahlen kompatibel machen Allgemeine Java-Themen 5
U (Java) Happy Numbers in Anlehnung an den Sieb des Eratosthenes (Glueckliche Zahlen) Allgemeine Java-Themen 1
J Array ohne vorher festgelegte Länge oder Wie wandle ich Zahlen in Zahlen mit anderen Basen um? Allgemeine Java-Themen 6
Cayton Bruchrechner stürzt bei eingabe negativer Zahlen ab Allgemeine Java-Themen 4
N Zahl mit bestimmter Länge und nur bestimmten Zahlen generieren lassen Allgemeine Java-Themen 7
P Datentypen String-Daten zu Byte-Zahlen konvertieren - Komme nicht weiter nach vielem versuchen :-/ Allgemeine Java-Themen 7
I Java-Programm: Zahlen in Worte Allgemeine Java-Themen 22
H String auf Zahlen prüfen Allgemeine Java-Themen 4
V iText Textfelder mit Zahlen! Allgemeine Java-Themen 2
M Rechnen mit kleinen Zahlen langsamer!? Allgemeine Java-Themen 11
Luk10 Römische Zahlen in Java Allgemeine Java-Themen 7
R Codehinweise: Algorithmus Größenvergleich von n Zahlen Allgemeine Java-Themen 5
GianaSisters ArrayList mit Zahlen Allgemeine Java-Themen 10
B User-Input aus Zahlen und Operatoren - beste Umsetzung? Allgemeine Java-Themen 8
S Fixe Zahlen vergleichen Allgemeine Java-Themen 4
D JTable -> 1Spalte nur zahlen Allgemeine Java-Themen 2
N Zahlen in Strings einer ArrayList sortieren Allgemeine Java-Themen 14
T Apache POI Export EXCEL - [Zahlen-Werte] Allgemeine Java-Themen 1
ModellbahnerTT Button mit Zahlen beschriften Allgemeine Java-Themen 1
J Zahlenkombination aus int-array, mit absteigenden Zahlen Allgemeine Java-Themen 6
R Runden von Zahlen Allgemeine Java-Themen 3
J Zahlen Rechtsbuendig in File schreiben Allgemeine Java-Themen 3
W POI - Formatierung für Zahlen Allgemeine Java-Themen 4
MQue Zahlen mit Border Allgemeine Java-Themen 2
T ungerade zahlen berechnen Allgemeine Java-Themen 3
N Zahlen mit Nachkommastellen aus Textfeldern einlesen Allgemeine Java-Themen 6
P Algoritmus für 3er-Paare von n Zahlen Allgemeine Java-Themen 12
A Fibonacci-Zahlen & kopfgesteuerte Schleifen & Strukt Allgemeine Java-Themen 8
J Suche regex-Pattern fuer Liste von Zahlen zwischen 0-100 Allgemeine Java-Themen 6
G die mittlere von 5 Zahlen nur mit if und else finden Allgemeine Java-Themen 48
M Rechnen mit sehr kleinen Zahlen Allgemeine Java-Themen 8
MQue Zahlen an alysieren Allgemeine Java-Themen 6
ARadauer Random keine Zahlen doppelt Allgemeine Java-Themen 4
V FileWriter und Zahlen (Kein Problem, nur Verständnisfrage) Allgemeine Java-Themen 4
G Strings die Zahlen enthalten sinnvoll sortieren (A2 < A10 Allgemeine Java-Themen 4
F 3 Zahlen "vereinfachen" Allgemeine Java-Themen 5
C double Zahlen mit drei NachkommaStellen in String umwandeln Allgemeine Java-Themen 2
A testen ob Primzahl dauert bei größeren zahlen extrem lange Allgemeine Java-Themen 8
E Hex- Zahlen in Datei Allgemeine Java-Themen 4
G Umrechnen von grossen Zahlen ins Hex-System Allgemeine Java-Themen 3
S Zahlen sortieren Allgemeine Java-Themen 3
D Zahlen innerhalb eines Strings auslesen Allgemeine Java-Themen 3
P rechnen mit extrem grossen zahlen Allgemeine Java-Themen 2
X Logische Operatoren auf binären Zahlen Allgemeine Java-Themen 2
F Array mit Zahlen drin sortieren Allgemeine Java-Themen 2
M Hilfe: Lotto: die 6 häufigsten generierten zahlen ausgeben Allgemeine Java-Themen 13
O String auf zahlen prüfen (java 1.3) Allgemeine Java-Themen 4
G Methode, die Buchstaben in Zahlen umwandelt? Allgemeine Java-Themen 13
S Integer-Zahlen in Excel-Sheet schreiben Allgemeine Java-Themen 10
M Lange Zahlen in Java Allgemeine Java-Themen 4
C zahlen einlesen Allgemeine Java-Themen 2
thE_29 Wie hex Zahlen darstellen Allgemeine Java-Themen 3
G Zahlen vergleichen Allgemeine Java-Themen 5
S Rechnen mit float Zahlen Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben