kostenloser Webspace werbefrei: lima-city


Das Zweierkomplement und C++

lima-cityForumProgrammiersprachenC/C++ und D

  1. Autor dieses Themas

    toolz

    Kostenloser Webspace von toolz

    toolz hat kostenlosen Webspace.

    Ich habe zwei Fragen zum selben Thema:
    Ich hole mir eine Intel-Format 32-Bit Zahl folgendermaßen aus einer Datei:
    unsigned int zahl = (unsigned int)read(dat) + 0x100 * (unsigned int)read(dat) + 0x10000 * (unsigned int)read(dat) + 0x1000000 * (unsigned int)read(dat);
    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?

    Mit anderen Worten:
    Wie überprüfe ich am schnellsten, ob 01010010... mit einer 0 anfängt?
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. 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:
    #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;
    }
    Wenn Du das erste Bit, also das Vorzeichenflag für signed integer, überprüfen willst, dann kannst Du folgendes machen:
    if(zahl & 0x80000000)
    {
        /* erstes Bit gesetzt */
    }
    else
    {
        /*erstes Bit nicht gesetzt */
    }
    Hierbei ist 0x80000000 die Hexadezimalschreibweise für 10000000000000000000000000000000 im Binärsystem.

    Edit: Die allgemeine Lösung wäre diese:
    bool is_bit_set(unsigned long i, int idx)
    {
        if(idx < 0 || idx > 31)
            return false;
        else
            return i & (1 << idx);
    }
    Wobei idx eine Zahl zwischen 0 und 31 sein sollte.

    Beitrag zuletzt geändert: 10.5.2011 20:43:11 von darkpandemic
  4. 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!
  5. 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
  6. 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
  7. 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):
    int zahl;
    i = i << 3; /* logischer Shift */
    i = i/8;    /* arithmetischer Shift */
    i = i*3;    /* Integer Multiplikation (wahrscheinlich IMUL r32, imm8) */
    Interessante Informationen zu diesem Thema findet man im ersten Kapitel von "Matters Computational". Das kann ich in diesem Zusammenhang empfehlen.
    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
  8. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!