Hä?
Danilo hat doch bestätigt, dass das gleiche rauskommt?
Wenn du uns die "exakten Werte" mitteilen würdest, könnte man vielleicht herausfinden, wie dein PB-Code aussehen soll.
Zum verständnis: Eine Variable vom Typ Long (=Integer auf 32bit Systemen) besteht (wie der Name "32bit System" vermuten lässt) aus 32 bits.
Also 32 "Schaltern", die jeweils an oder aus sein können (1 und 0).
So eine Long-Variable kann man aufteilen in 2 Word-Variablen (Word = 2Byte = 16bit = 2^16 = ~65k).
Diese "Words" nennt man dann Hi(gh) Word und Lo(w) Word. Also hohes Word und niedriges Word.
Das HiWord steht als erstes.
(Beispiel aus dem 10er System: Ich kann 100.000 aufteilen in 2 Gruppen die jeweils 100 groß sind.
Also kann ich in 100.000 genau zwei Zahlen speichern, die beide maximal 100 groß sind.
a = 99
b=500
summe = 99.500 = 100*99 + 500).
Nachdem aber alle Variablen letztendlich binär gespeichert sind, also wieder als 1 und 0,
kann ich anstatt zu multiplizieren, einfach die bits nach vorne schieben, wie beim ausschreiben der Zahl oben^^
Das macht "<< 16".
Es schiebt den Wert 16 bits nach vorne, also an die HiWord-Position.
Dementsprechend gilt.
summe = a<<16 + b (anstatt + wird bei solchen Aktionen halt | verwendet (warum auch immer, in PB zumindest macht es (meistens (meiner Erfahrung nach immer)) keinen Unterschied).
Oder auch. summe = a * 2^16 + b
Beim Rückwandeln wird das HiWord wieder um 16 bits verschoben. Diesmal in die andere Richtung, also an die LoWord Position.
Das Rückwandeln geht im Gegensatz zum Umwandeln nur mit der binären Operation Bitshift (eben das Verschieben der Bits um 16 Stellen (in dem Fall, man kann natürlich auch um 7 oder 3 Stellen verschieben, wenn das Sinn ergibt)).
Wenn du einfach durch 2^16 teilen würdest, hättest du ja einen Rest (eigentlich das LoWord).
Aber mit normaler mathematischer Division bekommst du keinen Rest, sondern einen u.U. arg hässlichen Dezimalbruch.
Je nach Größe des LoWords bekomsmt du also auch mit Runden ein falsches Ergebnis für das HiWord heraus.
Deswegen: BitShift um 16 Stellen.
Das eigentliche LoWord bekommst du heraus, indem du die Summe mit $FFFF "maskierst"
$FFFF in Binär ausgedrückt sind 16Bit. (also genau die Word-Größe).
Da wird ja auch eine 0 haben, die auch irgendwo Platz haben muss, sind $FFFF aber nicht 2^16, sondern 2^16-1.
Binär ausgedrückt: 16 Einser nach einander.
Von den Bits vor den 16 Bits ist keine Rede und es gilt, was bei unseren täglichen Zahlen auch gilt:
Führende Nullen werden weggelassen.
Wenn man jetzt die vollen 32bit beachtet, anstatt nur 16bit, stehen da nicht nur 16 Einser, sondern auch 16 Nuller.
$FFFF als Long in Binär ist also:
00000000000000001111111111111111
Und unser LoWord (312 als Beispiel sieht so aus)
00000000000000000000000100111000
Untereinanander geschrieben.
Code: Alles auswählen
00000000000000001111111111111111
00000000000000000000000100111000
Jetzt werden nur die Bits gesetzt, die in der "Maske" ($FFFF) auch gesetzt sind.
Das sind in dem Fall alle 16.
Also werden alle 16 Bits übernommen uns es kommt wieer 312 raus.
Ich könnte als Maske auch $C nehmen. Das ist 12 im Dezimalsystem und 1100 im Binärsystem.
Als Beispiel nehmen wir wieder 312.
Code: Alles auswählen
Debug RSet(Bin($c),16,"0")
var = 312
Debug RSet(Bin(var),16,"0")
Debug Bin(var & $C)
Debug var & $C
Das Ergebnis:
Code: Alles auswählen
0000000000001100 ;$C <- Maske
0000000100111000 ;312 im Binärsystem
0000000000001000 ;Nur die Bits sind 1, die in beiden Bitsequenzen 1 sind.
8 ;Das Ergebnis im Dezimalsystem
Diese Maskierung mit anderen Werten als $FFFF ergibt imho eigentlich gar keinen Sinn.
Damit kastriert man nur den Eingabewert und das ohne Rückmeldung.
Speicherplatz wird dadurch auch keiner gespart. Die Variable ist immer noch 4Byte groß, egal welche Maskierung man verwendet.
Lange Rede kurzer Sinn:
Auch wenn ich oben gezeigt habe, wie man eine Maskierung von $XYZ anwendet: Weglassen geht genauso.
Code: Alles auswählen
i5.i = 312
i6.i = -3109
j8.i = i6 << 16 | i5
Debug j8.i
Debug j8 >> 16
Debug j8 & $FFFF