C++ und der Shift-Operator

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
Leverator
Beiträge: 37
Registriert: Mo Jan 30, 2012 9:28 pm
Wohnort: ::1

C++ und der Shift-Operator

Beitrag von Leverator » So Okt 14, 2012 10:17 am

Moin zusammen,

ich habe hier ein Problem, das mir Kopfzerbrechen bereitet.
Aber zunächst mal der Code:

Code: Alles auswählen

#include <iostream>
#include <stdint.h>

int main( int argc, char *argv[] ) {

        int64_t x;
        int64_t y;
        int64_t _M = 24;

        x = 1024 << _M;
        y = 2048 << _M;

        std::cout << "x = " << x << std::endl;
        std::cout << "y = " << y << std::endl;

        std::cout << "x*y = " << x*y << std::endl;
        std::cout << ( (x*y)>>_M ) << std::endl;


        return 0;
}                     
Startet man nach dem Kompilieren dieses Beispiel, erscheint folgende Ausgabe:

Code: Alles auswählen

/tmp$ ./test 
x = 0
y = 0
x*y = 0
0

Und nun die goldene Frage: WARUM?
Für x erwarte ich den Wert 17179869184. Y muss entsprechend doppelt so hoch sein.

Hintergrund dieses Beispiels ist eine Berechnung von Fliesskommawerten mit Hilfe von ganzzahligen Ints. Darum verwende ich int64_t um genügend Platz für die Nachkommastellen zu haben.
Ich möchte also einfach eine Operation wie a*b durchführen. Ich definiere den Punkt an dem das Komma gesetzt werden soll mit _M. Hier also das 24. Bit.

Wer mag mir da weiterhelfen?

Vielen Dank,
Lev

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: C++ und der Shift-Operator

Beitrag von Kerli » So Okt 14, 2012 10:46 am

Leverator hat geschrieben:

Code: Alles auswählen

x = 1024 << _M;
y = 2048 << _M;
Hier musst du aufpassen. Konstanten sind ohne nähere Typangaben entweder int oder double. Wenn du also wie in diesem Fall einen größeren Datentyp möchtest musst du entweder L (long), LL (long long) oder UL/ULL (unsigned long (long)) and die Konstante anhängen. (zb. 1024L)
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

Leverator
Beiträge: 37
Registriert: Mo Jan 30, 2012 9:28 pm
Wohnort: ::1

Re: C++ und der Shift-Operator

Beitrag von Leverator » So Okt 14, 2012 11:08 am

Hallo Kerli,

danke für diesen Hinweis.

Da meine Daten eigentlich als int32_t-Array vorliegen, habe ich den o.g. Code wie folgt geändert:

Code: Alles auswählen

x = static_cast<int64_t>(1024) << _M;
y = static_cast<int64_t>(2048) << _M;
Die Ausgabe sieht schon besser aus, jedoch immernoch nicht so wie ich es mir vorstelle:

Code: Alles auswählen

/tmp$ ./test 
x = 17179869184
y = 34359738368
x*y = 0
0
Hast Du noch weitere Hinweise,

Grüße,
Lev

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: C++ und der Shift-Operator

Beitrag von Xin » So Okt 14, 2012 11:31 am

Kerli hat geschrieben:
Leverator hat geschrieben:

Code: Alles auswählen

x = 1024 << _M;
y = 2048 << _M;
Hier musst du aufpassen. Konstanten sind ohne nähere Typangaben entweder int oder double.
Solange sie keinen Punkt enthalten sind sie int, haben sie einen Punkt, so sind sie double.

Ein int mit dem Wert 1024 << 24 ergibt 0, da Du einen 32 Bit int hast, wo Du eine Zahl mit 10 Bit um 24 Bits verschiebst. Das signifikante Bit 10, was 1024 repräsentiert, fliegt damit raus. Übrig bleiben 32 Nullen.

Wenn Du zwei 64 Bit Zahlen, die auf den Bits 0-31 nur '0'en haben (das ist bei 1024<<24 und 2024<<24 der Fall), multiplizierst, kommen 64 '0'en raus. Eine 64Bit-Zahl, die nur Nullen enthält ist... 0.
Alles was drüber liegt, wird abgeschnitten. Integer sind eben keine Fließkommazahlen.

Deine Multiplikation benötigt also entweder 128Bit-Integers oder Fließkommazahlen mit dem Risiko, dass die Multiplikationen nicht mehr exakt sind.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
oenone
Beiträge: 223
Registriert: Do Sep 01, 2011 2:42 pm
Wohnort: Bremen
Kontaktdaten:

Re: C++ und der Shift-Operator

Beitrag von oenone » Mi Okt 17, 2012 1:22 pm

Leverator hat geschrieben:Die Ausgabe sieht schon besser aus, jedoch immernoch nicht so wie ich es mir vorstelle:
Was stellst du dir denn vor?

Antworten