Seite 1 von 1

Arithmetisches und logisches Shiften

Verfasst: 17.07.2016 22:06
von CSHW89
Hallo Leute,

ich habe gerade festgestellt, dass PureBasic nur arithmetisches Shiften erlaubt, heißt:

Code: Alles auswählen

a.b = %11111001
a >> 2
Debug RSet(Bin(a,#PB_Byte),8,"0")
;       %11111110
; statt %00111110
In Java gibts z.b. zwei Operatoren '>>' für arithmetisches Shiften und '>>>' für logisches Shiften. Gibt es da eine Möglichkeit das logische Shiften umzusetzen? Vorweg ich benutze den Typ Integer nicht Byte und will alle 32 bzw. 64 Bits benutzen. Also größere Variablen kann ich nicht nehmen.

lg Kevin

Re: Arithmetisches und logisches Shiften

Verfasst: 17.07.2016 23:31
von man-in-black
Hi,

was hälst du von xor nach bitshift?

Code: Alles auswählen

a>>2
a!%11000000
(Ungetestet. Kein pb zur hand)

Edit: statt %11000000 kann man auch nen int mit 0 füllen und
n-mal shiften (damit ist dann sowohl 32 als auch 64 abgedeckt)
Bei xor muss man aber beim variablentyp und dem vorzeichenbit aufpassen, sofern vorhanden.

Mfg
MIB

Re: Arithmetisches und logisches Shiften

Verfasst: 17.07.2016 23:34
von NicknameFJ
Hi,

benutze den Datentyp .a wenn du unbedingt einen Byte-Typ verwenden willst. Warum eigentlich nicht Integer?

Code: Alles auswählen

a.a = %11111001

a >> 2

Debug RSet(Bin(a,#PB_Byte),8,"0")
;       %11111110
; statt %00111110 
ManinBlack meint vermutlich a & 255 um von signed zu unsigned zu kommen. Funktioniert hier aber nach dem Bitshift nicht da dies ja nur zur Anzeige des signed Bytetyps .b als unsigned dient (Interpretation der Bitfolge) und nichts mit dem eigentlichen Bitshift zu tun hat.

NicknameFJ

Re: Arithmetisches und logisches Shiften

Verfasst: 17.07.2016 23:53
von man-in-black
Ließ nochmal :p
Warum eigentlich nicht Integer?
Vorweg ich benutze den Typ Integer (komma?) nicht Byte und will alle 32 bzw. 64 Bits benutzen.
Und nein, ich meine kein signed - unsign durch &.
Xor invertiert in dem fall die ersten bits

Re: Arithmetisches und logisches Shiften

Verfasst: 17.07.2016 23:54
von mk-soft
P.S Vorherigen Beitrag überarbeitet wegen blödsinn...

Hiermit solltest Du alles machen können... Eben noch schnell mit 64Bit erweitert

Code: Alles auswählen

;-TOP
; Kommentar     : Bitshift and Rotation
; Author        : mk-soft
; Second Author : 
; Datei         : .pb
; Version       : 1.01
; Erstellt      : 09.06.2007
; Geändert      : 18.07.2016
; 
; Compilermode  :
;
; ***************************************************************************************

; Bitshift left rotation
Procedure ROL32(value.l, count.l = 1)

  !mov eax, dword [p.v_value]  
  !mov ecx, dword [p.v_count]
  !rol eax, cl
  ProcedureReturn
  
EndProcedure

; Bitshift right rotation
Procedure ROR32(value.l, count.l = 1)

  !mov eax, dword [p.v_value]  
  !mov ecx, dword [p.v_count]
  !ror eax, cl
  ProcedureReturn
  
EndProcedure

; Bitshift left rotation
Procedure ROL64(value.q, count.q = 1)

  !mov rax, qword [p.v_value]  
  !mov rcx, qword [p.v_count]
  !rol rax, cl
  ProcedureReturn
  
EndProcedure

; Bitshift right rotation
Procedure ROR64(value.q, count.q = 1)

  !mov rax, qword [p.v_value]  
  !mov rcx, qword [p.v_count]
  !ror rax, cl
  ProcedureReturn
  
EndProcedure

; Bitshift left shift
Procedure SHL8(value.b, count.l = 1)

  !xor eax, eax
  !mov al, byte [p.v_value]  
  !mov ecx, dword [p.v_count]
  !shl al, cl
  ProcedureReturn
  
EndProcedure

; Bitshift right shift
Procedure SHR8(value.b, count.l = 1)

  !xor eax, eax
  !mov al, byte [p.v_value]  
  !mov ecx, dword [p.v_count]
  !shr al, cl
  ProcedureReturn
  
EndProcedure

; Bitshift left shift
Procedure SHL16(value.w, count.l = 1)

  !xor eax, eax
  !mov ax, word [p.v_value]  
  !mov ecx, dword [p.v_count]
  !shl ax, cl
  ProcedureReturn
  
EndProcedure

; Bitshift right shift
Procedure SHR16(value.w, count.l = 1)

  !xor eax, eax
  !mov ax, word [p.v_value]  
  !mov ecx, dword [p.v_count]
  !shr ax, cl
  ProcedureReturn
  
EndProcedure

; Bitshift left shift
Procedure SHL32(value.l, count.l = 1)

  !mov eax, dword [p.v_value]  
  !mov ecx, dword [p.v_count]
  !shl eax, cl
  ProcedureReturn
  
EndProcedure

; Bitshift right shift
Procedure SHR32(value.l, count.l = 1)

  !mov eax, dword [p.v_value]  
  !mov ecx, dword [p.v_count]
  !shr eax, cl
  ProcedureReturn
  
EndProcedure

; Bitshift left shift
Procedure SHL64(value.q, count.q = 1)

  !mov rax, qword [p.v_value]  
  !mov rcx, qword [p.v_count]
  !shl rax, cl
  ProcedureReturn
  
EndProcedure

; Bitshift right shift
Procedure SHR64(value.q, count.q = 1)

  !mov rax, qword [p.v_value]  
  !mov rcx, qword [p.v_count]
  !shr rax, cl
  ProcedureReturn
  
EndProcedure

Procedure.w BSWAP16(value.w)
  !xor eax,eax
  !mov ax, word [p.v_value]
  !rol ax, 8
  ProcedureReturn
EndProcedure

Procedure BSWAP32(value.l)
  !mov eax, dword [p.v_value]
  !bswap eax
  ProcedureReturn
EndProcedure

Procedure BSWAP64(value.q)
  !mov rax, qword [p.v_value]
  !bswap rax
  ProcedureReturn
EndProcedure

;-Test

x = $80
x = shr8(x,2)
Debug RSet(Bin(x),8,"0")

x = $02
x = shl8(x,2)
Debug RSet(Bin(x),8,"0")

x = $01020304
x = bswap32(x)
Debug RSet(Hex(x),8,"0")

x = $0102
x = bswap16(x)
Debug RSet(Hex(x),8,"0")


x = %1001
x = shl32(x, 4)
Debug Bin(x)

x = %1001
x = shr32(x, 4)
Debug Bin(x)

x = %1001
x = rol32(x, 29)
Debug Bin(x)

x = %1001
x = ror32(x, 5)
Debug Bin(x)

x = %1001
x = shl64(x, 4)
Debug Bin(x)

x = %1001
x = shr64(x, 4)
Debug Bin(x)

x = %1001
x = rol64(x, 29)
Debug Bin(x)

x = %1001
x = ror64(x, 5)
Debug Bin(x)

Re: Arithmetisches und logisches Shiften

Verfasst: 18.07.2016 00:28
von CSHW89
Vielen Dank erstmal an alle.
@man-in-black:
Gibt leider zwei Probleme. Erstens kann, aber muss nicht das höchste Bit gesetzt sein. Wenn nicht würde xor nicht funktionieren. Da wäre aber "value & ~(%11000..)" bzw "value & (%00111..) möglich. Allerdings ist die 2 keine Konstante, somit funktioniert das leider auch nicht.

@mk-soft:
Super, das würde klappen. Ist nur schade, dass dafür ein Procedureaufruf draufgeht. Da ich allerdings nur bestimmte Masken verschiebe, werde ich es vermutlich mit einem vorher berechneten Array machen. Also:

Code: Alles auswählen

; statt
value = SHR32(#MeineMaske, shift)
; das
value = MeineMaske(shift)
Wobei, wie gesagt, MeineMaske() das Array ist, welches die vorher berechneten Werte mit SHR32() speichert. Ist vermutlich noch etwas schneller. Schade nur, dass PB kein '>>>' Operator besitzt.

lg Kevin

Re: Arithmetisches und logisches Shiften

Verfasst: 18.07.2016 00:43
von man-in-black
Hi,

gut, denkfehler^^
Dann musst du eben erst die ersten bits auf 1 setzen und dann
Invertieren. (Shift-or-xor). Die länge von der maske kannst du variabel gestalten. S. Meinen ersten post. (Habs vor deiner antwort dort nachgetragen.)

edit: vergesst, was ich vorgeschlagen habe. war gestern wohl schon zu spät^^