Wie mit 64Bit Blöcken arbeiten
Dieter
- programmiertechnik
0 Bio0 Gunnar Bittersmann-1 Dieter0 Dieter0 Vinzenz Mai
0 Christian Kruse
0 Sven Rautenberg
Hallo,
also ein normaler Computer, benutzt i.d.R. ein 32 Bit Prozessor.
Jetzt gibt es aber Verschlüsselungsalgorithmen, die z.B. eine Blöcklänge von 128 Bit, bzw. 64 Bit linker & 64 Bit rechten Block besitzen.
Dazu gehört z.B. AES, aber auch DES benutzt Zeitweise 48 Bit Blöcke.
Auf einem normalen Computer kann man in einer Integer Variable leider nur max. 32 Bit speichern, so dass man einen gesamten Block (linke/rechte Hälfte) nicht in einer Variablen speichern kann.
Wie wird dieses Problem in Programmen gelöst?
Wird jetzt ein 64 Bit großer linker Block in zwei 32 Bit Blöcke unterteil?
Oder wird jedes Byte in ein Array gespeichert, und dann jedes Arrayelement entsprechend "behandelt"?
Grüße
Dieter
Sup!
Entweder, die Programmiersprache kapselt für Dich die Hardware und stellt 64-Bit-Operationen auch auf einem 32-Bit-Prozessor zur Verfügung, oder Du musst Dich selbst drum kümmern, und einen 64-Bit-Block aus 2x32 oder 4x16 oder 8x8 Bit zusammensetzen, und ggf. die Operationen aufteilen, so dass sie auf Teilblöcken ausgeführt werden. Bei einer Addition z.B. addierst Du erst die niedrigwertigen Sub-Blöcke, dann die höherwertigen, bei einer logischen Operation ist die Ausführungsreihenfolge egal, etc..
Gruesse,
Bio
Hallo,
aber wie sieht es denn z.B. mit Bit-Verschiebungen aus?
Dort wäre es doch schon relevant ob man 2x32 Bit Blöcke verschiebt oder 1x64Bit block, oder?
Grüße
Dieter
你好 Dieter,
aber wie sieht es denn z.B. mit Bit-Verschiebungen aus?
Dort wäre es doch schon relevant ob man 2x32 Bit Blöcke verschiebt oder
1x64Bit block, oder?
Wenn die Plattform das nicht nativ einbaut (viele Prozessoren können mit
Größen, die der natürlichen Größe nicht entsprechen, umgehen) muss man das
halt per Software emulieren. Ist dann zwar sehr langsam, aber nicht zu
ändern.
再见,
克里斯蒂安
Hi Dieter,
Auf einem normalen Computer kann man in einer Integer Variable leider nur max. 32 Bit speichern,
Je nach Prozessor.
In C gibt es neben den Typen int bzw. unsigned int auch long int bzw. unsigned long int mit doppelter Länge.
Gruß,
Gunnar
Hallo,
In C gibt es neben den Typen int bzw. unsigned int auch long int bzw. unsigned long int mit doppelter Länge.
Dabei ist die "doppelte Länger" allerdings 32 Bit, denn früher wurde 16 Bit für int benutzt.
Grüße
Dieter
Hallo,
In C gibt es neben den Typen int bzw. unsigned int auch long int bzw. unsigned long int mit doppelter Länge.
also wenn ich z.B:
unsigned long long test = 10 000 000 000; (ohne Leerzeichen)
schreibe, dann erhalte ich sowohl von DevCpp als auch von GCC den Fehler:
Integer constant is to larg for "long" type.
Auch wenn ich per scanf(); eine große Zahl, allerdings kleiner als 2^62 einlese, wird diese per prinft("%u",zahl); immer mit 4.294.967.295 ausgegeben.
Laut Wikibooks kann man dort allerdings 64 Bit zahlen speichern, weiß jmd. woran das liegen kann?
Benutze WinXP.
Grüße
Dieter
Hallo Dieter
Auch wenn ich per scanf(); eine große Zahl, allerdings kleiner als 2^62 einlese, wird diese per prinft("%u",zahl); immer mit 4.294.967.295 ausgegeben.
wie wäre es, wenn Du Dir die Werte von
ULLONG_MAX
ULONG_LONG_MAX
ausgeben lassen würdest, die typischerweise in limits.h definiert werden.
Freundliche Grüße
Vinzenz
Hallo,
obwohl für die Konstanten 2^62 definiert wurde, erhalte ich bei der Ausgabe dennoch nur die 4,2 Mrd (2^32).
Grüße
Dieter
obwohl für die Konstanten 2^62 definiert wurde, erhalte ich bei der Ausgabe dennoch nur die 4,2 Mrd (2^32).
signed vs. unsigned
Hallo,
dies ist auf unsigned.
Allerdings:
long long:
signed ist der Bereich bei ca.: -2^61 bis +2^61
unsigned: 0 bis 2^62
int:
signed ca.: -2^31 bis +2^31
unsigned: 0 bis 2^32
Je nach Compiler kann bei signed der Betrag des positive Bereich um 1 kleiner sein, weil die 0 auf 2 Arten dargestellt werden kann.
Grüße
Dieter
你好 Dieter,
Je nach Compiler kann bei signed der Betrag des positive Bereich um 1
kleiner sein, weil die 0 auf 2 Arten dargestellt werden kann.
Nein. Wie die 0 dargestellt wird ist auf x86-Plattformen definiert, das
machen alle Compiler gleich. Es kann aber je nach Plattform variieren.
再见,
克里斯蒂安
你好 Dieter,
In C gibt es neben den Typen int bzw. unsigned int auch long int bzw.
unsigned long int mit doppelter Länge.Dabei ist die "doppelte Länger" allerdings 32 Bit, denn früher wurde 16
Bit für int benutzt.
Wie gross genau die Datentypen sind, hängt stark von der Plattform und
manchmal auch vom Compiler ab. Häufig ist int die natürliche Größe auf einer
Plattform, genau wie long (also sizeof(int) == sizeof(long)), muss aber
nicht so sein. Viele Compiler unterstützen dann noch long long, was dann
das doppelte der natürlichen Größe darstellt.
Um die Plattform-Probleme zu umgehen, definiert der POSIX-Standard
sys/types.h, wo genauer festgelegte Datentypen definiert sind: int8_t,
u_int8_t, int16_t, u_int16_t, int32_t, u_int32_t, int64_t, u_int64_t.
Vermutlich fehlen da noch einige Typen, aber das sind wohl die wichtigsten
Integer-Typen.
再见,
克里斯蒂安
Moin!
Auf einem normalen Computer kann man in einer Integer Variable leider nur max. 32 Bit speichern, so dass man einen gesamten Block (linke/rechte Hälfte) nicht in einer Variablen speichern kann.
Wie wird dieses Problem in Programmen gelöst?
Jeder vernünftige Prozessor hat zusätzlich zu seinen Registern noch diverse Flags, welche man für die unterschiedlichsten Dinge nutzen kann.
Für arithmetische Belange gibt es beispielsweise das Carry-Flag, welches z.B. bei Additionen das Übertragsbit enthält, das Zero-Flag (wird gesetzt, wenn eine Operation Null ergibt), das Overflow-Flag (für vorzeichenbehaftete Rechenoperationen) sowie das Negativ-Flag (gesetzt, wenn der Integerwert negativ ist). Ich muß allerdings zugeben, dass diese Ausführungen sich konkret nur auf die Prozessorreihe 6502/6510 beziehen (bei dem weiß ich es), ich kann mir aber kaum vorstellen, dass x86er das grundlegend anders lösen können.
Eine Addition beliebig großer Werte wird mit dem Carry-Flag dann schrittweise vom LSB zum MSB durchgeführt. Vor Beginn der Addition wird das Carry gelöscht, die Addition des LSB setzt oder löscht das Carry, sofern ein Übertrag errechnet wurde, und mit diesem Ergebnis wird das nächst höhere Byte/Word/Longword addiert.
Wer sich damit assemblermäßig nicht rumquälen will, und seine Programmiersprache auch keine direkte Unterstützung liefert, muß sich vermutlich nach einer passenden Mathe-Bibliothek umsehen. :)