Arithmetisches und logisches Shiften

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Arithmetisches und logisches Shiften

Beitrag 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
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Benutzeravatar
man-in-black
Beiträge: 362
Registriert: 21.08.2006 17:39

Re: Arithmetisches und logisches Shiften

Beitrag 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
Zuletzt geändert von man-in-black am 18.07.2016 00:33, insgesamt 1-mal geändert.
(hab alles, kann alles, weiß alles!!^^)

Bild
Benutzeravatar
NicknameFJ
Beiträge: 324
Registriert: 03.06.2007 14:36
Wohnort: Von der Sonne aus gesehen der dritte Planet

Re: Arithmetisches und logisches Shiften

Beitrag 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
PS: Alle im Text enthaltenen Schreibfehler sind beabsichtigt und dienen der Belustigung aller

Bild
Benutzeravatar
man-in-black
Beiträge: 362
Registriert: 21.08.2006 17:39

Re: Arithmetisches und logisches Shiften

Beitrag 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
Zuletzt geändert von man-in-black am 17.07.2016 23:55, insgesamt 1-mal geändert.
(hab alles, kann alles, weiß alles!!^^)

Bild
Benutzeravatar
mk-soft
Beiträge: 3855
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Arithmetisches und logisches Shiften

Beitrag 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)
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: Arithmetisches und logisches Shiften

Beitrag 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
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Benutzeravatar
man-in-black
Beiträge: 362
Registriert: 21.08.2006 17:39

Re: Arithmetisches und logisches Shiften

Beitrag 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^^
(hab alles, kann alles, weiß alles!!^^)

Bild
Antworten