BMPs einlesen
-
Hallo,
//Converts a four-character array to an integer, using little-endian form int toInt(const char* bytes) { return (int)(((unsigned char)bytes[3] << 24) | ((unsigned char)bytes[2] << 16) | ((unsigned char)bytes[1] << 8) | (unsigned char)bytes[0]); } //Reads the next four bytes as an integer, using little-endian form int readInt(ifstream &input) { char buffer[4]; input.read(buffer, 4); return toInt(buffer); }Wollte nur mal kurz nachfragen, warum man in der toInt-Funktion noch mal die unsigned char casts braucht bzw. was passiert, wenn man sie weglässt. Unterschiede kanns ja eigentlich nur dann geben, wenn das MSB 1 ist, aber da doch hier sowieso nur Bitmuster verodert und am Ende nach int gecastet werden, müsste man sich den cast doch sparen können oder übersehe ich was?
-
Was hat das mit BMPs zu tun?
Hmm: Probiere es aus. Du kannst dir vorher gern das Bitmuster von -1 bzw. 255 anschauen und die Darstellung in der verschiedenen Typen int/char unsigned/signed.
-
banshee schrieb:
aber da doch hier sowieso nur Bitmuster verodert und am Ende nach int gecastet werden, müsste man sich den cast doch sparen können oder übersehe ich was?
Shift von negativen Zahlen ist undefiniert. Auf meiner Plattform wird das Vorzeichen übernommen und der Rest geshiftet, also -1 << 8 = -256.
Das bitweise zu verodern ist wiederum undefiniert. Es kommt auf jeden Fall nicht das richtige raus.Der letzte Cast nach int ist übrigens unnötig.
-
sbump schrieb:
banshee schrieb:
aber da doch hier sowieso nur Bitmuster verodert und am Ende nach int gecastet werden, müsste man sich den cast doch sparen können oder übersehe ich was?
Shift von negativen Zahlen ist undefiniert.
ich glaube da versiehst du dich, shift durch negative zahlen ist undefiniert
-1<<8ist wohl definiert
1<<-8ist undefiniert
in c++ ist <<n aequivalent zu *(1<<n) und >>n zu /(1>>n).beim shift wird der linke operant implizit zu int bzw unit konvertiert, ein negatives char waere ein negatives int.
ich denke das beispiel ist auch ein wenig verwirrend/suboptimal. eigentlich sollte man dort die ganze zeit mit unsigned char arbeiten.
und eigentlich gehoert der thread in den c++ bereich, da es sich um grundlagen von c++ handelt

-
Dieser Thread wurde von Moderator/in rapso aus dem Forum Spiele-/Grafikprogrammierung in das Forum C++ (auch C++0x und C++11) verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Ich habe damit jetzt etwas rumgespielt und es ist irgendwie seltsam. In einigen Fällen mit gesetztem MSB gibt es Unterschiede, die daher rühren, dass am Ende nach int gecastet wird. Wenn man die bytes da nicht unsigned interpretiert, kommt bei negativen Zahlen logischerweise auch als int eine negative raus.
Ich habe dann einfach mal versucht, nach unsigned int zu casten und da passiert etwas wirklich Merkwürdiges. Wenn ich das char array mit {-1,0,0,0} initialisiere, das Bitmuster von(bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0]also 000000000 00000000 00000000 11111111 ergibt, dann interpretiert ein cast nach unsigned int das als -1 anstatt 255. Die 0en werden also anscheinend einfach abgeschnitten. Wieso das?
PS: Ja, prinzipiell ist es schon noch reines C++ und ich wollte zuerst auch da eröffnen, aber es ging in erster Linie ums BMP-Laden, wo dieser Code herkommt.
-
rapso schrieb:
ich glaube da versiehst du dich, shift durch negative zahlen ist undefiniert
-1<<8ist wohl definiert
1<<-8ist undefiniert
in c++ ist <<n aequivalent zu *(1<<n) und >>n zu /(1>>n).Nein, ich habe das richtig formuliert:
The value of
E1 << E2isE1left-shiftedE2bit positions; vacated bits are zero-filled. IfE1has an unsigned type, the value of the result isE1× 2E2, reduced modulo one more than the maximum value representable in the result type. Otherwise, ifE1has a signed type and non-negative value, andE1× 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.@banshee: Dein letztes Beispiel ist
0 | 0 | 0 | -1, was halt in deiner Plattform -1 ergibt.
-
sbump schrieb:
@banshee: Dein letztes Beispiel ist
0 | 0 | 0 | -1, was halt in deiner Plattform -1 ergibt.Aber warum ist das so? Das heißt ja, dass das MSB aka. der Negativschalter auf Position 25 steckt (also MSB des 4. Bytes). Warum werden die drei Bytes vorher einfach verworfen bzw. nicht zur Interpretation der Zahl herangezogen? Was ergibt dann z.B. 1 0 0 -1?