Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Zahlenkreis
fuulf - Fr 05.03.10 22:56
Titel: Zahlenkreis
Hallo,
kann man einen Variablen-Typ so deklarieren, dass ein Zahlenkreis entsteht?
Und zwar möchte ich einen Typ haben, der die Zahlen 1, 2, 3, 4, 5 hat. Wenn eine Variable dieses Typs auf 5 gesetzt wird und dann eins hinzuaddiert wird, soll die Variable den Wert 1 annhemnen. Wenn die Variable den Wert 1 hat und 1 abgezogen wird, dann soll die Variable den Wert 5 haben.
Tilo - Fr 05.03.10 23:17
Ich bin mir nicht sicher ob es in Delphi die Möglichkeit gibt Operator zu überladen (C# und Co können das glaube ich).
Ohne Überladung gleibt Dir nur der Weg über eine Klasse "TZahlenkreis".
privater Inhalt:
wert,Basis:integer;
=> Wert beinhaltet den aktuellen Wert, Basis die "Größe" des Zahlenkreises, hier z.b. 5
Methoden:
Create(Initwert,Basis:integer);
Destroy (könnte weg gelassen werden, da nur 2 private Integer)
Add(aValue:integer) => Addiert aValue auf wert auf und achtet darauf dass wert immer zwischen 1 und Basis liegt
Sub(aValue:integer) => Zur Faulheit des Nutzers, ruft nur Add(-Value) auf
integer GetWert() => liefert den aktuellen Wert
SetWert(aValue) => setzt wert auf aValue, rechnet aValue in einen gültigen Bereich oder wirft deine Fehlermeldung wenn aValue außerhalb des Bereiches liegt (Designfrage)
Nur so als Anregung. Die Klassenvariante hat den Vorteil, dass Du sie für Zahlenkreis verschiedene Größen nutzen kannst.
GetWert und SetWert kann man z.B. auch private gestalten und über eine Property nach aßen Kapseln.
Bergmann89 - Sa 06.03.10 10:52
Hey,
bei den neueren Delphi-Versionen geht das. Ansonsten, wie Tilo schon gesagt hat, musst du dir eigenen Funktionen schreiben. Das geht mit mod ganz gut: zahl := (zahl + 1) mod 5 das ist zwar jetzt ein Zahlenkreins von 0-4 aber ich denk mal damit sollte sich trotzdem was anfangen lassen...
MfG Bergmann.
Hidden - Sa 06.03.10 11:12
Hi :)
Ist es dir den Aufwand denn wirklich wert, einen eigenen Typen zu deklarieren, nur um ein mod ZahlMax bei jedem Hinschreiben zu sparen? (ZahlMax: Konstante, oder auch Variable).
Alle gängigen Datentypen wie Integer oder Cardinal ergeben übrigens solch einen Zahlenkreis. :lupe: Wenn ein Integerwert 2^31 überschreitet, fängt er wieder bei -2^31 an. Das gleiche gilt für Cardinal mit 2^32 und 0.
Das Ganze nennt man dann Überlauf, und ist meißtens ungewollt und eine Fehlerquelle.
Wenn aber zwei Cardinal(oder Integer-)zahlen voneinander abgezogen werden sollen, wird das intern afaik so gemacht, dass für 15 - 3 beispielsweise 15 und (2^32-3) addiert werden. Das Ergebnis ist dann 15-3, weil für binär dargestellte Zahlen streng genommen gilt:
n = n + k*2^32, also auch 15 + (-3) = 15 + (2^32 - 3).
lg,
fuulf - Sa 06.03.10 19:27
Hallo,
ja gerade weil ja Integer und Cardinal genau so sind, wie ich das gerne hätte, hatte ich gedacht es wäre leicht einen vergleichbaren Typ selbst zu definieren. Ist Delphi 5 neu genug dazu?
Also es soll nicht nur plus und minus klappen, sondern auch zum Beispiel Wurzel und Potenz.
Und es soll nicht nur am Ende ein möglicher Überlauf berücksichtigt werden, sondern auch bei jeder Teilrechnung. Also zB 2^6 --> 2^1 --> 2 und nicht 2^6 --> 64 --> 4
Geht das?
Hidden - Sa 06.03.10 20:24
Hi :)
Du wirst die einzelnen Funktionen schon selbst implementieren müssen, soweit sie nicht kommutativ sind, du also den Übertrag (+ k*B) bis hinten durchziehen kannst.
Bei Addition und Multiplikation funktioniert das noch, also
Quelltext
1: 2: 3: 4:
| (a+kB + b+kB + (x+kB)*(a+kB)*(b+kB) + b+kB + a+kB) mod B = (a + b + b + a + kB) mod B + (xyz) mod B + ((kB)²x + (kB)²y + (kB)²z + kBxy + kBxz + kByz) mod B = (a + b + b + a) mod B + xyz mod B = (a + b + xyz + b + a) mod B |
Im Schritt von 2 auf 3 fällt jeder Term mit B weg, weil er modulo B ja wieder null ist. Mit Wurzeln klappt das dann natürlich nicht mehr. Aber für den Datentyp müsstest du ja die Wurzelfunktion überladen oder neu deklarieren. Vordefinierte Funktionen schlucken ja nur Integer, Cardinal, etc. Die kannst du nur nehmen und auf den Typen casten, wenn du entweder danach offen oder versteckt modulo rechnest, oder die Rechnung Additiv ist.
lg,
Xion - So 07.03.10 11:42
Ich hätte jetzt gesagt so geht es:
var Zahlenkreis: 1..5;
geht es aber nicht...da frag ich mich welchen Sinn die obige Schreibweise dann hat :roll:
Hidden - So 07.03.10 14:02
Hi :)
Die Schreibweise bezieht sich glaube ich rein auf die Übergabe von Konstanten, und ist dort nur zur Fehlervermeidung, wei bei der Frage lokale/globale Variablen, gedacht. Das ist jedenfalls der einzige Fall, in dem der Compiler bei mir mal gemeckert hat. Von der internen Darstellung des Datentyps ändert sich da nichts.
lg,
ffgorcky - So 07.03.10 17:02
Also ich würde da jetzt auch sagen, dass Du einfach nur eine normale Integer-Variable nimmst und für das Auslesen dieser eine Funktion schreibst, die dann einfach (x mod 5)+1 rechnet.
Ich hatte jetzt gerade irgendwie an SET und GET gedacht, aber das ist ja (soweit ich meine, das noch zu wissen) nur in C# möglich.
Hidden - So 07.03.10 17:36
Hi :)
Set und Get gehen soweit ich dich verstehe auch in Delphi, aber eben nur bei propertys von Objekten.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| type TMyNumCircle = class(TObject) private FNum: Integer; FNumMax: Integer; private procedure SetNum(aNewNum: Integer); public property Value: Integer read FNum write SetNum; end; |
Proof of concept: Ja. Aber Anwenden: Schreib' lieber ein mod FNumMax bei jedem nötigen Zwischenschritt..
lg,
fuulf - Mo 08.03.10 18:45
Ja, ich denke am einfachsten ist es, es bei jedem Zwischenschritt einzeln hinzuschreiben.
Vielen Dank an euch für eure Hilfe :-)
F34r0fTh3D4rk - Mo 08.03.10 19:56
Hidden hat folgendes geschrieben : |
Alle gängigen Datentypen wie Integer oder Cardinal ergeben übrigens solch einen Zahlenkreis. :lupe: Wenn ein Integerwert 2^31 überschreitet, fängt er wieder bei -2^31 an. Das gleiche gilt für Cardinal mit 2^32 und 0.
Das Ganze nennt man dann Überlauf, und ist meißtens ungewollt und eine Fehlerquelle. |
Liegt es nicht eher an der Zweierkomplement-Darstellung, dass man beim Überschreiten der Integer-Grenzen im Negativen landet?
Was passiert denn, wenn man weitermacht und auch über die Grenze der Negativen Zahlen hinausläuft? Da sind dann nämlich alle Bit voll und weiter geht es dann wirklich nicht mehr.
Hidden - Mo 08.03.10 20:13
Hi :)
Die Übergänge sind ja von 0..2147483648..-2147483648..0..2147483648..-2147483648.
Du landest ja nicht bei -0, -1, -2, .. sondern eben beim negativen Maximum, und gehst dann wieder über Null den Weg, den du schon gekommen bist. :lupe:
lg,
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!