Warum kann PB kein unsigned long bzw. int ?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: Warum kann PB kein unsigned long bzw. int ?

Beitrag von CSHW89 »

Noch ein Zusatz zur Frage, wozu: Bitmasks bzw. Bitboards. Beim Schach werden sie z.B. häufig benutzt. Jedes der 64 Felder repräsentiert ein Bit in einem 64-Bit-Integer. Mehrere dieser Bitmasks repräsentieren dann eine Stellung. Eine zeigt z.B. alle weißen Figuren an, eine zeigt alle Läufer an, ect... Die möglichen Züge können mit Bit-Operationen und zuvor berechneten Bitmasks deutlich schneller berechnet werden.
Unsigned quads wären da schon recht hilfreich. Allerdings fehlt PureBasic eine andere entscheidene Sache, die Java z.B. hat, den "unsigned right shift operator". Dieser muss leider emuliert werden, was den Geschwindigkeitsvorteil wieder etwas dämpft.

Code: Alles auswählen

test.l = %11000000000000000000000000000000
Debug Bin(test, #PB_Long)   ; 11000000000000000000000000000000
testa.l = test >> 1
Debug Bin(testa, #PB_Long)  ; 111000000000000000000000000000000    (die erste 1 ist eigentlich falsch)
;testb.l = test >>> 1   ; Gibt es leider nicht
;Debug Bin(testb, #PB_Long) ; 011000000000000000000000000000000
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
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Warum kann PB kein unsigned long bzw. int ?

Beitrag von STARGÅTE »

>> "Jedes der 64 Felder repräsentiert ein Bit in einem 64-Bit-Integer."
Das war also der wahre Grund für den Technologiesprung von 32 nach 64 bit, wegen Schach :lol:
Interessanter Ansatz.

Zum echten Right Shift, muss man halt ASM nutzen, was aber nicht langsamer ist.

Code: Alles auswählen

test.l = %11000000000000000000000000000000
Debug Bin(test, #PB_Long)   ; 11000000000000000000000000000000
testa.l = test >> 1
Debug Bin(testa, #PB_Long)  ; 111000000000000000000000000000000    (die erste 1 ist eigentlich falsch)
Define testb.l
! MOV eax, dword [v_test]
! SHR eax, 1
! MOV dword [v_testb], eax
Debug RSet(Bin(testb, #PB_Long), 32, "0") ; 011000000000000000000000000000000
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Warum kann PB kein unsigned long bzw. int ?

Beitrag von NicTheQuick »

Für ein unsigned shift gibt es immerhin einen ASM-Befehl, den man mit Inline-Assembler leicht einbauen kann. Aber frag mich nicht wie. :lol:

Edit: Oh, zu langsam.

@STARGATE: Da du grad hier bist. Kannst du mir erklären, was Purebasic hier macht?

Code: Alles auswählen

; Define vara.l = var >> 1
  MOVSXD r15,dword [v_var]
  SAR    r15,1
  MOV    rax,r15
  PUSH   rax
  POP    rax
  MOV    dword [v_vara],eax
Was ist an MOVSXD so besonders, warum muss es in r15 und was soll das PUSH und POP da überhaupt? Das sieht alles so unnötig aus.
Bild
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Warum kann PB kein unsigned long bzw. int ?

Beitrag von STARGÅTE »

Das Push Pop ist irgendwie unnötig ja. Aber durch den One-Pass-Compiler gibt es vermutlich keine Optimierungsroutine.
Da hier mit x64 Register gearbeitet wird (weil es die Wortgröße des Prozessors ist),
muss das Vorzeichen von der Long "erweitert" werden (MOV Sign eXtension Doubleword) damit das SAR richtig funktioniert,
sonst würde SAR ja ein 0-Bit reinschieben.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Warum kann PB kein unsigned long bzw. int ?

Beitrag von mk-soft »

Schon in ASM Fertig 8)
Link: Bitshift and Rotation
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Warum kann PB kein unsigned long bzw. int ?

Beitrag von ccode_new »

Hi!

Ich habe da mal ne Frage dazu.

Ist das MOVSXD nicht extra für negative Zahlen gedacht ?

Ist das hier dann bei negativen Zahlen nicht falsch?

Beispiel:

Code: Alles auswählen

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

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

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

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

EndProcedure

Procedure RShift()
!  MOVSXD r8, dword [v_var]
!  SAR    r8,1
!  MOV    rax,r8
; !  PUSH   rax
; !  POP    rax
!  MOV    dword [v_vara],eax
EndProcedure

Define.l var = -16 ;Negative Zahl
Define vara.l ; = var >> 1

Debug var >> 1 ;Bin(var >> 1)
Debug SHR32(var, 1) ;Bin(SHR32(var, 1)) ;Negativ ?

RShift()
Debug vara ;Bin(vara)
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Warum kann PB kein unsigned long bzw. int ?

Beitrag von mk-soft »

SHR32 oder SHR64 ist ein Unsigned schrieben rechts. Braucht man manchmal ...

Code: Alles auswählen

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

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

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

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

EndProcedure

lVal.l = $F234F567

; Swap words
Debug Hex(lVal, #PB_Long)
lVal = SHR32(lVal, 16) | SHL32(lVal, 16)
Debug Hex(lVal, #PB_Long)

MOVSXD kümmert sich darum das Signed Werte richtig geladen werden. Also von ein Signed DWord nach ein Signed QWord
Wenn also das Signed Bit auf 1 ist (Negativer Wert) werden alle Bits im automatisch gefüllt, damit dieser eine negativer Wert bleibt.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Warum kann PB kein unsigned long bzw. int ?

Beitrag von ccode_new »

Code: Alles auswählen

; Bitshift right shift
Procedure.q SHR64(value.q, count.q = 1);   Bitshift right shift
 
  CompilerIf #PB_Compiler_Processor=#PB_Processor_x64
    !mov rax, qword [p.v_value]
    !mov rcx, qword [p.v_count]
    !shr rax, cl
    ProcedureReturn
  CompilerElse
    Protected v1.q
    v1 = ~($FFFFFFFFFFFFFFFF << (64-count))
    ProcedureReturn value>>count & v1
  CompilerEndIf
 
EndProcedure

Define.q ts = %0110010101101011011011100110000101000100100

ts = SHR64(ts, #PB_Date_Day)
Debug PeekS(@ts, 5, #PB_Ascii)

Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Antworten