Das Zweierkomplement und C++
lima-city → Forum → Programmiersprachen → C/C++ und D
bit
code
datei
ersten post
format
frage
integer typ
integer typen
kaffee
linken operator
operator
potenz
sorgen
standard
string
unterschiedlichen ergebnissen
unterschiedlichen plattformen
zahl
ziffer
zweck
-
Ich habe zwei Fragen zum selben Thema:
Ich hole mir eine Intel-Format 32-Bit Zahl folgendermaßen aus einer Datei:
Kann ich das so machen? Jetzt ist diese aber nach dem Zweierkomplement gebildet und ich mss überprüfen, ob die erste Zahl eine 1 oder eine 0 ist. Wie mache ich das am Besten?unsigned int zahl = (unsigned int)read(dat) + 0x100 * (unsigned int)read(dat) + 0x10000 * (unsigned int)read(dat) + 0x1000000 * (unsigned int)read(dat);
Mit anderen Worten:
Wie überprüfe ich am schnellsten, ob 01010010... mit einer 0 anfängt? -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Hallo toolz,
du kannst auch, sofern dat ein input-stream ist, folgendes machen:
unsigned int zahl; dat.read((char*)&zahl, sizeof(zahl));
An die erste Ziffer (im Dezimalsystem) kommst Du am einfachsten über stringstream:
Wenn Du das erste Bit, also das Vorzeichenflag für signed integer, überprüfen willst, dann kannst Du folgendes machen:#include <iostream> #include <sstream> using namespace std; int main() { stringstream ss; string str; unsigned int zahl = 1234; ss << zahl; ss >> str; if(str.at(0) == '1') cout << str.at(0) << endl; else cout << str << endl; return 0; }
Hierbei ist 0x80000000 die Hexadezimalschreibweise für 10000000000000000000000000000000 im Binärsystem.if(zahl & 0x80000000) { /* erstes Bit gesetzt */ } else { /*erstes Bit nicht gesetzt */ }
Edit: Die allgemeine Lösung wäre diese:
Wobei idx eine Zahl zwischen 0 und 31 sein sollte.bool is_bit_set(unsigned long i, int idx) { if(idx < 0 || idx > 31) return false; else return i & (1 << idx); }
Beitrag zuletzt geändert: 10.5.2011 20:43:11 von darkpandemic -
Meiner Meinung nach wäre die performanteste Lösung:
if (zahl >> 31 == 0) { /* Kaffee */ } else { /* Kuchen */ }
Aber die Variante mit dem "Ver-Und-en" sollte den Zweck auch vollkommen erfüllen! -
Hallo i-spacke,
grundsätzlich sind '&' (AND r/m32, imm32) und '>>' (SHR r/m32, imm8) gleich schnell. Allerdings muss man bei '>>' und auch '<<' immer aufpassen, dass der erste Operand nicht 0 (Null) ist, da das Verhalten in diesem Fall weder im C- noch im C++-Standard definiert ist. D.h. es kann auf unterschiedlichen Plattformen zu unterschiedlichen Ergebnissen kommen.
Beitrag zuletzt geändert: 12.5.2011 20:55:04 von darkpandemic -
Hi darkpandemic,
Prinzipiell hast du Recht, weswegen man in Java ja auch den ">>>"-Operator verwenden würde. Soweit ich weiß ist es in C, C++ und C# jedoch so, dass wenn man ein unsigned int als linken Operator hat (und darum ging es im ersten Post, wenn ich das richtig sehe), ein logischer Shift durchgeführt wird und man sich darum also keine Sorgen machen muss.
Letztenendes ist es wahrscheinlich wohl eine Frage des Geschmacks und Stils. :)
LG Spacke -
Hallo i-spacke,
in C/C++ werden die Operatoren '<<' und '>>' immer auf logische Shifts abgebildet (auch für signed integer Typen). Arithmetische Shifts werden nur dann verwendet, wenn man einen signed integer Typ mit einer 2-er Potenz multiplizier oder dividiert (bei gcc bin ich mir sicher bei den anderen glaube ich es nur):
Interessante Informationen zu diesem Thema findet man im ersten Kapitel von "Matters Computational". Das kann ich in diesem Zusammenhang empfehlen.int zahl; i = i << 3; /* logischer Shift */ i = i/8; /* arithmetischer Shift */ i = i*3; /* Integer Multiplikation (wahrscheinlich IMUL r32, imm8) */
Und das steht glaube ich auch drin, dass in C/C++ auch für logische Shifts nicht definiert ist was 0 << n bzw. 0 >> n ergeben soll.
Edit: Ok ich habe gerade gesehen (Kapitel 1.1.5 in obigem Buch), dass ich ein wenig Bockmist erzählt habe. Das Problem ist der rechte nicht der linke Operand.
Beitrag zuletzt geändert: 13.5.2011 17:09:02 von darkpandemic -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage