Mysteriöser Integer-Datentyp

  • Hallo Pfreunde des profunden Programmierens!

    Gerade stellt mich der Integer-Datentyp vor Rätsel. Vielleicht versteht ihn ja einer besser und kann mir helfen?

    Problem: Ich möchte aus einer Datei einen Zwei-Byte-Wert auslesen. Dieser kann negativ sein. Also habe ich den R-Basic-Datentyp integer verwendet. Der umfaßt zwei Byte und geht von -32k bis +32k.
    Der Wert in der Datei beträgt 0xFD20, in Bits 1111 1101 0010 0000. Dies sollte (nach meinem Verständnis) einer negativer Wert sein, da das höchste Bit gesetzt ist.
    Wenn ich diesen Wert aber einlese (oder im Code der Variablen zuweise), enthält die integer-Variable diesen Wert: 32767 = 0x7FFF = 0111 1111 1111 1111.

    Und das verstehe ich nicht ;( . Könnte mir das einer erklären?

    Ich hatte mir das immer so vorgestellt: Word und integer umfassen beide zwei Byte. Der Word-Datentyp nutzt alle Bits zur Zahlendarstellung von 0 bis 65535. Der integer-Datentyp nutzt das höchste Bit, um festzuhalten, ob es eine negative oder positive Zahl ist, und verwendet die restlichen Bits zur Zahlendarstellung. Daher ist der Maximalwert mit 32k nur halb so hoch.
    Also könnte man doch die 0xFD20 zuweisen, er erkennt am höchsten Bit, daß es eine negative Zahl ist und verwendet die restlichen Bits als 0x7D20 = 32032.
    Aber so ist es ja nicht. Und wäre eigentlich auch seltsam, weil ein altes Bildformat doch keine Bildbreite von 32000 Pixeln haben sollte! Irgendwas verstehe ich da offenbar noch nicht.

    Nachtrag:
    Damit verbunden das zweite Problem: Die Datei speichert im Big-Endian-Format, Geos nutzt aber Little Endian. Also steht in der Variablen nach dem Einlesen 0x20FD (das funktioniert übrigens). Nun müßte ich die beiden Bytes aber vertauschen. Beim Word-Datentyp klappt das problemlos, aber integer kommt wieder 07FFF raus. Das ist wohl ein Folgedenkfehler.

  • In einem anderen Programm habe ich C-Code gefunden, der den fraglichen Fall behandelt. Vielleicht hilft es ja bei der Lösungsfindung. Mir ist der entscheidende Unterschied leider noch nicht aufgegangen.

    Code
    i64 w_raw, h_raw;
    i64 w, h;
    
    
    w_raw = de_geti16be_p(&pos);
    h_raw = de_geti16be_p(&pos);
    is_compressed = (w_raw<0);
    w = is_compressed ? ((-w_raw)+1) : (w_raw+1);
    h = h_raw+1;
  • Hallo Sebi,
    die Erklärung ist simpel. R-BASIC begrenzt bei Integer die Werte auf +/-32k. Macht also keinen Übertrag. Ob das jetzt eine sinnvolle Entscheidung war, darüber kann man streiten. Es gibt da Pros und Cons.
    Fakt ist, du musst dich an Word wenden.
    Gruß
    Rainer

    Es gibt 10 Arten von Menschen - die einen wissen was binär ist, die anderen nicht.

  • Hallo Rainer!

    Danke für die Erklärung. Ich hatte dann auch Word verwendet und halt das höchste Bit abgefragt.
    R-Basic hat aber keinen eigenen Befehl für das Komplement, oder? Habe ich dann mit NOT(a)+1 umgesetzt. Ach ja, dabei mußte ich das NOT nochmal klammern - dann sah es so aus: (NOT(a)) + 1 - weil sonst die +1 auch negiert wurde. Hätte gedacht, das NOT beziehe sich nur auf den geklammerten Ausdruck dahinter.

    Interessant, daß es verschiedene Ansätze für die integer-Umsetzung gibt. Das bedeutet ja dann für R-Basic, daß man integer nicht nutzen kann, um negative Werte einzulesen, da negative Werte das höchste Bit 0x8000 gesetzt haben und dadurch schon gleich die Höchstgrenze reißen? Also dann immer Word nehmen und nachbearbeiten?

    Salute!

  • Hallo Sebi,

    (NOT(a)) + 1 - weil sonst die +1 auch negiert wurde. Hätte gedacht, das NOT beziehe sich nur auf den geklammerten Ausdruck dahinter.


    Komisch, die dopplete Klammerung sollte nicht nötig sein. Bin gerade sehr bussy, kann das daher momentan nicht ausprobieren, aber logsich ist das nicht.

    Das bedeutet ja dann für R-Basic, daß man integer nicht nutzen kann, um negative Werte einzulesen, da negative Werte das höchste Bit 0x8000 gesetzt haben und dadurch schon gleich die Höchstgrenze reißen?


    Nein, wenn du muss dem Read-Befehl sagen, wie er die beiden Bytes zu interpretieren hat, vorzeichenbehaftet oder vorzeichenlos. Dann kannst du auch Integerwerte lesen.
    Gruß
    Rainer

    Es gibt 10 Arten von Menschen - die einen wissen was binär ist, die anderen nicht.