| Autor |
Beitrag |
VampireSilence
      
Beiträge: 109
Erhaltene Danke: 5
C# (VS 2008 Express), PHP/MySQL, Windows XP
|
Verfasst: Do 02.12.10 22:13
Ich sitze aus rein experimentellen Gründen gerade daran, einen neuen Basistypen zu schreiben, und zwar einen Int128.
Dieser soll eben mit 128 Bits arbeiten und so weit ist das auch kein Problem - habe dazu einfach eine Klasse mit entsprechendem bool[128]-Array erstellt. Jetzt ist es aber leider so, dass ich 2 Variablen vom Typ Int128 nicht addieren kann, bzw. dass der Compiler dies nicht zulässt. Auch das einfache zuweisen einer Zahl ist nicht möglich. Mir ist klar, dass dies notwendig ist, da der Compiler ja nicht hinter ein komplexes Objekt schauen kann und deshalb wollte ich euch fragen, ob ihr dafür eine Lösung kennt.
mfg
- VampireSilence
|
|
jaenicke
      
Beiträge: 19340
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Do 02.12.10 22:20
|
|
Th69
      

Beiträge: 4807
Erhaltene Danke: 1061
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Fr 03.12.10 14:25
Hallo VampireSilence,
ein bool[128]-Array ist aber eindeutig der falsche Datentyp dafür. Nimm einfach zwei Int64 (long) und programmiere die entsprechenden Operatoren aus (+, - und * sollten ja recht einfach gehen, einzig für die Division '/' wirst du ein bißchen mehr überlegen müssen - erinnere dich an die Grundschulmathematik, nur daß du jetzt im Binärsystem rechnen mußt).
Zum Rechnen mit den Überträgen wirst du auch die Bitoperationen benötigen, s. z.B. Bitoperationen in C#.
|
|
jaenicke
      
Beiträge: 19340
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 03.12.10 14:41
Es geht ja um experimentelle Zwecke, deshalb ist die Performance wohl egal. Deshalb ist das hier durchaus sinnvoll, weil man besser sehen kann, welche Bits gesetzt sind beim Debuggen.
|
|
Th69
      

Beiträge: 4807
Erhaltene Danke: 1061
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Fr 03.12.10 14:47
Ja, schön und gut, aber ein bool ist ja ein logischer Datentyp (also nur true und false). Wie soll man dem bool-Array dann eine Zahl zuweisen?
C#-Quelltext 1:
| bool[128] array = { false, ... , true }; |
So ???
Und dann damit auch noch rechnen...
|
|
Yogu
      
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: Fr 03.12.10 14:50
Wie wäre es mit einem impliziten Operator von int64 in den neuen Basistyp?
|
|
VampireSilence 
      
Beiträge: 109
Erhaltene Danke: 5
C# (VS 2008 Express), PHP/MySQL, Windows XP
|
Verfasst: Fr 03.12.10 20:26
@jaenicke
Danke, das ist genau das, was ich brauchte. Ist nur schade, dass ich den "="-Operator nicht überladen kann und somit eine direkte Zuweisung trotzdem nicht möglich ist.
@Th69
Du musst wissen, dass Zahlen binär nur aus wahr und falsch bestehen. Ein Int64 ist also auch nicht viel mehr, als ein bool[64]. Zwei davon zu einem Int128 zusammenzufügen, wäre also nur ein umständlicher Umweg. Da ein bool ein Bit repräsentiert, kann ich damit leichter arbeiten und warscheinlich ist es auch wesentlich performanter. Das rechnen damit funktioniert genau, wie im Dezimalen, nur dass 1 + 1 = 10 gilt. Eine Addition erfolgt demnach also bitweise (so wie es intern auch mit Int64 und Konsorten getan wird). Einem bool selbst kann keine Zahl zugewiesen werden, aber aus einer Folge von wahr und falsch, kannst du eine Zahl repräsentieren und auch eine dezimale Zahl darstellen. Dies erfolgt dann mit
Quelltext 1:
| Dezimalzahl = Bit[127] * 2 ^ 127 + Bit[126] * 2 ^ 126 + Bit[125] * 2 ^ 125 + Bit[124] * 2 ^ 124 + ... etc. |
mfg
- VampireSilence
|
|
jaenicke
      
Beiträge: 19340
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 03.12.10 20:40
|
|
Th69
      

Beiträge: 4807
Erhaltene Danke: 1061
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Fr 03.12.10 21:03
Und nicht zu vergessen: der Speicherplatz. Ein 'bool' belegt genau 1 Byte (8 bit), d.h. dein Datentyp wäre mindestens 128 Byte groß (anstatt bei zwei Int64 nur 16 Byte)...
Und VampireSilence, dein Satz
| Zitat: |
Ein Int64 ist also auch nicht viel mehr, als ein bool[64].
|
stimmt so also ganz und gar nicht!
|
|
jaenicke
      
Beiträge: 19340
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 03.12.10 21:13
Übrigens gibt es auch die BitArray Klasse bei .NET. Mal so nebenbei. 
|
|
Yogu
      
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: Fr 03.12.10 21:30
VampireSilence hat folgendes geschrieben : | | Ist nur schade, dass ich den "="-Operator nicht überladen kann und somit eine direkte Zuweisung trotzdem nicht möglich ist. |
Nein, es ist ein Segen, dass der Zuweisungsoperator nicht überladen werden kann! Das würde im reinen Chaos enden (siehe C++).
Was du brauchst, ist eine Umwandlung zwischen normalen Zahlentypen und deiner Klasse. Das geht mit den implicit- und explicit-Operatorn. Letztere erfordert es, dass der Datentyp, in den konvertiert werden soll, angegeben werden muss. Beim impliziten Operator passiert die Konvertierung ganz still und heimlich.
Die Konvertierung von int und int64 würde ich implizit machen, da keine Probleme auftreten können. Andersrum sollte es explizit sein, da die Zahl auch mal zu groß sein könnte, und dabei eine Exception geworfen werden muss.
C#-Quelltext 1: 2: 3: 4: 5: 6: 7:
| public static implicit operator Int128(int value) { }
public static explicit operator int(Int128 value) { } |
Zuletzt bearbeitet von Yogu am So 05.12.10 18:59, insgesamt 1-mal bearbeitet
|
|
VampireSilence 
      
Beiträge: 109
Erhaltene Danke: 5
C# (VS 2008 Express), PHP/MySQL, Windows XP
|
Verfasst: Sa 04.12.10 14:50
Ok, mein Fehler lag also darin, anzunehmen ein bool wäre ein Bit. Das glaube ich euch jetzt auch einfach mal, aber mal ernsthaft: wofür zum Teufel braucht ein Datentyp, der sowieso nur wahr oder falsch speichert ACHT Bits ?! Was will man da bitte drin speichern ? ^^ Das ist doch die reinste Ressourcendekadenz.
@jaenicke
Ist die BitArray-Klasse nicht ein bisschen zu komplex und performancelastig dafür ?
| Zitat: | | Hier irrst du dich. Performanter ist es ganz bestimmt nicht. Denn so übernimmst du die ganzen bitweisen Operationen statt dies einfach dem Prozessor zu überlassen. |
Sorry, aber das verstehe ich nicht. Selbstverständlich übernimmt der Prozessor meine Operationen, ich meine: was denn sonst ? Die Festplatte sicher nicht. Das klingt zugegeben etwas naiv, aber ich weiss es einfach nicht besser. Dazu fehlt mir das Hintergrundwissen.
@Topic
Ich werd dann wohl doch einfach 2 Int64 verbinden, das erscheint mir bisher die beste Lösung zu sein.
mfg
- VampireSilence
|
|
jaenicke
      
Beiträge: 19340
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 04.12.10 15:26
VampireSilence hat folgendes geschrieben : | | aber mal ernsthaft: wofür zum Teufel braucht ein Datentyp, der sowieso nur wahr oder falsch speichert ACHT Bits ?! |
Wie willst du denn dem Prozessor oder dem Arbeitsspeicher einzelne Bits geben?
Stell dir nur mal vor der Speichermanager würde einzelne Bits reservieren. Das wäre ein Overhead...
VampireSilence hat folgendes geschrieben : | | Was will man da bitte drin speichern ? ^^ Das ist doch die reinste Ressourcendekadenz. |
False ist als Null definiert, alles andere als True.
Deshalb klappt auch der Vergleich mit True (if xy = true) in den meisten Sprachen nicht.
VampireSilence hat folgendes geschrieben : | | Ist die BitArray-Klasse nicht ein bisschen zu komplex und performancelastig dafür ? |
Wahrscheinlich auch kaum mehr als dein Zugriff.
VampireSilence hat folgendes geschrieben : | | Sorry, aber das verstehe ich nicht. Selbstverständlich übernimmt der Prozessor meine Operationen, ich meine: was denn sonst ? |
Beispiel (vereinfacht):
Du möchtest zwei Bytes addieren. Jetzt packst du die Bytes in die Register und schickst zusätzlich ein ADD als Assemblerbefehl zum Prozessor. Zack, ein Prozessortakt und du hast das Ergebnis.
Jetzt stell dir stattdessen vor du schickst die einzelnen Bits um das auszurechnen, was jeweils einen Takt mindestens braucht. Was meinst du wohl ist schneller? 
|
|
VampireSilence 
      
Beiträge: 109
Erhaltene Danke: 5
C# (VS 2008 Express), PHP/MySQL, Windows XP
|
Verfasst: So 05.12.10 18:25
| Zitat: | Jetzt stell dir stattdessen vor du schickst die einzelnen Bits um das auszurechnen, was jeweils einen Takt mindestens braucht. Was meinst du wohl ist schneller?  |
Ok, das ist natürlich einleuchtend. Ich hätte ja nicht ahnen können, dass das .NET Framework immernoch derartig umständlich mit den Daten umgeht, anstatt einfach alles in einem Takt zu verarbeiten. Man sollte meinen Microsoft hätte das in all den Jahren entsprechend optimiert, aber da war mein Optimismus wohl fehl am Platz. ^^
mfg
- VampireSilence
|
|
Yogu
      
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: So 05.12.10 18:46
VampireSilence hat folgendes geschrieben : | | Zitat: | Jetzt stell dir stattdessen vor du schickst die einzelnen Bits um das auszurechnen, was jeweils einen Takt mindestens braucht. Was meinst du wohl ist schneller?  |
Ok, das ist natürlich einleuchtend. Ich hätte ja nicht ahnen können, dass das .NET Framework immernoch derartig umständlich mit den Daten umgeht, anstatt einfach alles in einem Takt zu verarbeiten. Man sollte meinen Microsoft hätte das in all den Jahren entsprechend optimiert, aber da war mein Optimismus wohl fehl am Platz. ^^ |
Da hast du was falsch verstanden.
Ein Wert vom Typ int ist in einem 32-Bit-System in einer Speichereinheit gespeichert. Wenn nun zwei solche Zahlen addiert werden, werden sie beide als 32-Bit-Zahl weitergereicht, über einen elektronischen Baustein in einem Rutsch addiert, und das Ergebnis wieder irgendwo anders gespeichert. Normalerweise braucht eine CPU dafür einen Takt.
Wenn du nun einen 128-Bit-Typ erstellen willst und dafür ein bool-Array verwendest, sieht der Speicher ganz anders aus: An einer Stelle steht ein Verweis auf eine andere Speicherstelle. Dort findet sich an erster Stelle die Anzahl der Einträge (128), und dann folgen 128 Byte, die jeweils 0 oder 1 enthalten. Insgesamt werden also (auf einem 32-Bit-System) 128 + 4 + 4 = 136 Byte belegt. Wenn du nun addieren willst, musst du das in C# selbst schreiben. Also: Du erstellst ein drittes Array mit 128 Bool-Werten (es müssen 132 Byte auf dem RAM reserviert werden). Dann addierst du die niedrigsten beiden Bits und speicherst sie in das Ergebnis-Array (Ein Bit laden, das andere Bit laden, addieren, speichern -> mindestens 4 Takte). Den Überlauf schreibst du in den zweiten Eintrag des Ergebnis-Arrays. Und das ganze musst du nun 128 mal machen. Was glaubst du, wie viele Takte dabei zusammenkommen?
.NET ist an sich überhaupt nicht langsam, und die Programme sind auch sehr gut optimiert. Allerdings simulierst du praktisch eine Recheneinheit des Prozessors, und das ist dann eben auch nicht besonders schnell.
Aber für das Verständnis sollte das überhaupt keine Rolle spielen; denn da kommt es schließlich nicht in erster Linie auf die Performance an.
|
|
Th69
      

Beiträge: 4807
Erhaltene Danke: 1061
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: So 05.12.10 18:53
Das erinnert mich jetzt an eines meiner ersten großen Programme auf dem C-16. Dort hatte ich in BASIC (!) ein Programm namens "Prozessor" geschrieben, das die Assembler-Befehle emuliert -)
Leider reichte irgendwann der Speicher (16KB!!!) nicht mehr für das Programm aus, um alle Befehle umzusetzen (von der Geschwindigkeit will ich jetzt gar nicht mal reden  )
|
|
VampireSilence 
      
Beiträge: 109
Erhaltene Danke: 5
C# (VS 2008 Express), PHP/MySQL, Windows XP
|
Verfasst: So 05.12.10 19:17
@Yogu
So wie du das erklärst, würde das aber bedeuten, dass man garkeine neuen Basistypen erstellen kann, sondern einfach nur (fast) alles danach aussehen lässt, obwohl hinter den Berechnung im Hintergrund etwas ganz anderes steckt. Es ist also in dem Falle notwendig den Int128 direkt im Prozessor zu implementieren, um einen "echten" davon deklarieren zu können. Oder auf deutsch: Ich kann mir die Finger blutig tippen, aber ein exaktes Äquivalent zu Int32 und Int64 wird es bis dahin niemals geben können.
mfg
- VampireSilence
|
|
jaenicke
      
Beiträge: 19340
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 05.12.10 19:22
VampireSilence hat folgendes geschrieben : | | Oder auf deutsch: Ich kann mir die Finger blutig tippen, aber ein exaktes Äquivalent zu Int32 und Int64 wird es bis dahin niemals geben können. |
Das ist zwar richtig, aber du kannst dennoch einen performanten Ersatz schreiben. Nur musst du dann die vorhandenen 32-Bit bzw. 64-Bit Operationen des Prozessors auch nutzen. Und das kannst du nicht, wenn du für jedes Bit einzelne Berechnungen ausführst, die dann eben jeweils einzeln berechnet werden müssen.
Das ist wie wenn du ein Brot backen willst, das nicht in den Ofen passt. Jetzt kannst du entweder zwei halb so große Stücke backen und zu einem großen Brot zusammensetzen oder du kannst jede Scheibe einzeln backen. Was geht wohl schneller? 
|
|
|