Bit Twiddling Hacks

Hier kann alles mögliche diskutiert werden. Themen zu Purebasic sind hier erwünscht.
Flames und Spam kommen ungefragt in den Mülleimer.
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Beitrag von ZeHa »

Kaeru Gaman hat geschrieben:PS:
> sind die Vergleichsoperatoren <= und >= langsamer als < und > ?
ich würde mal raten, dass das garnicht feststeht, sondern von beiden zu verarbeitenden werten abhängt....
Den CMP-Befehl gibt es ebenfalls in mehreren Ausführungen, je nachdem ob z.B. zwei Bytes verglichen werden, oder zwei Words, oder zwei DWords, oder ein Byte mit einem DWord, oder ein DWord mit einem Pointer auf ein DWord usw. usf., aber es spielt keine Rolle dabei, ob er < oder <= vergleicht, weil das wie gesagt erst beim Sprung entschieden wird und nicht beim Vergleich.
Bild     Bild

ZeHa hat bisher kein Danke erhalten.
Klicke hier, wenn Du wissen möchtest, woran ihm das vorbeigeht.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

aye, ok... thnx
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

Ab Pentium benötigen alle bedingten Sprünge (also ausser JMP) die selbe Taktzeit. Ausnahme: JCXZ/JECXZ (wertet das (E)CX-Register aus).
Vergleiche (CMP) können nur mit identischen Register/Variablen-Grössen durchgeführt werden. Ausnahme: Der zweite Operand ist eine Konstante (Zahlenwert).
Das Beispiel mit Sign funktioniert mit PB, weil für Rechts-Shift SAR verwendet wird; kann bei anderen Sprachen fehlschlagen (signed-unsigned). Wer SAR für Divisionen durch 2-Potenzen einsetzt, muss bei negativen Werten aufpassen, weil SAR anders rundet (in Richtung minus unendlich). Kleines Beispiel:

Code: Alles auswählen

Debug -101 / 4     ;-25 wie erwartet
Debug -101 >> 2    ;-26 !
Gruss
Helle
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Beitrag von ZeHa »

Helle hat geschrieben:Vergleiche (CMP) können nur mit identischen Register/Variablen-Grössen durchgeführt werden. Ausnahme: Der zweite Operand ist eine Konstante (Zahlenwert).
Naja die Zahl der Ausnahmen ist schon recht groß.
Laut Intel-Beschreibung gibt's für CMP insgesamt 14 verschiedene Opcodes, je nachdem wie groß die Werte sind (8, 16 oder 32 Bit) und ob sie als Konstante, als Referenz oder als Register angegeben wurden.

EDIT: Und zwar nicht nur für den zweiten Wert, sondern auch für den ersten


(Zumindest laut diesem Dokument: click, Seite 116)
Bild     Bild

ZeHa hat bisher kein Danke erhalten.
Klicke hier, wenn Du wissen möchtest, woran ihm das vorbeigeht.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Helle hat geschrieben:Wer SAR für Divisionen durch 2-Potenzen einsetzt, muss bei negativen Werten aufpassen, weil SAR anders rundet (in Richtung minus unendlich). Kleines Beispiel:

Code: Alles auswählen

Debug -101 / 4     ;-25 wie erwartet
Debug -101 >> 2    ;-26 !
Um Stringoperationen unicodefähig zu machen, muss man die Anzahl Characters ja in Bytes umrechnen. D. h. 5 Zeichen sind entweder 5 oder 10 Bytes.

Vorher habe ich immer

Code: Alles auswählen

x*SizeOf(Characters)       ; Ergibt 1 (ASCII) oder 2 (Unicode)
verwendet; mittlerweile nehme ich aber immer

Code: Alles auswählen

x<<#PB_Compiler_Unicode         ; Konstante ist immer 0 oder 1
Kann man doch gefahrlos tun, oder?

Und dies ist genau ein Beispiel was ich mit meiner Aussage "Bit schneller als Multplikation". Stimmt das so?
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

@ZeHa: Ist ein Handbuch für den PentiumII, aktuell ist Dokument 253666.
Ändert aber nichts: Du willst z.B. Byte mit DWord vergleichen, und das geht nicht. Darum geht´s.

Gruß
Helle
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Kaeru Gaman hat geschrieben:
(sizeof(int) * CHAR_BIT - 1)
bekommt man 0 für positiv und 1 für negativ.
wenn man 1 und -1 haben will, muss man noch 1-2*sign rechnen.
Ooooder man rechnet

Code: Alles auswählen

sign = 1|v>>31
:)
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

AND51 hat geschrieben:Ooooder man rechnet

Code: Alles auswählen

sign = 1|v>>31
:)
kann ich nicht nachvollziehen....?
klappt zwar, aber rechne das mal bitte vor, ich steig nicht durch...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Komisch, jetzt wo du fragst und ich länger drüber nachdenke: Ich weiß es auch nicht (wirklich)... :freak:

Ich versuchs trotzdem, denn so habe ich es mir zumindest gedacht:

Durch das >>31 bleibt nur das Vorzeichen-Bit (jenes ganz links) übrig, welches für eine positive oder null (0) oder negative (1) Zahl steht. Dieses Bit wird an erster Stelle geholt und dann wird |1 angewendet;
so gesehen (und das verstehe ich nicht) dürfte das Ergebnis doch immer 1 sein?!

Der 31er-Rechtsschift ergibt jedoch nicht 1, sondern 1<<32-1 :o
Hilfe, ich komme auch durcheinander...

Bis auf das ganz linke Bit müss(t)en doch alle anderen verloren gehen, oder?


// Edit:
Hilfe, was ist hier los?

Code: Alles auswählen

one=1
Debug Bin(one<<31>>31)
Hier müsste doch 1 das Ergebnis sein?
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Beitrag von Danilo »

AND51 hat geschrieben:// Edit:
Hilfe, was ist hier los?

Code: Alles auswählen

one=1
Debug Bin(one<<31>>31)
Hier müsste doch 1 das Ergebnis sein?
PB macht signed Shifts, und da wird beim Rechtsverschieben um 31
das Vorzeichen aufgefüllt.
Was Du machen möchtest ist bestimmt (a>>31)&1.

Code: Alles auswählen

Macro SignL(a)
  ((a>>31)&1)
EndMacro

a.l = -1
Debug SignL(a)
a + 1
Debug SignL(a)
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Antworten