Seite 1 von 1

Variable als Unsigned byte?

Verfasst: 03.08.2016 19:38
von DarkSoul
Hallo Forum,

wie bekomme ich eine Variable als unsigned byte? Also 0 - 255 statt -128 - 127? :oops:

Hilfe schreibt:
Purebasic offers native support for unsigned variables with byte and word types via the ascii (.a) and unicode (.u) types
Ascii wird aber ab 5.50 nicht mehr unterstützt. :?

Oder bin ich zu geizig und man nimmt heutzutage selbst für ein Bool ein ganzes .i?

Ich quetsche oft bis zu 8 Booleans in dieselbe Byte-Variable. :)

Re: Variable als Unsigned byte?

Verfasst: 03.08.2016 19:49
von NicTheQuick
Den ASCII-Datentyp gibt es natürlich immer noch. Hast du es überhaupt mal selbst ausprobiert?

Code: Alles auswählen

a.a = 255
b.b = 255
Debug a
Debug b
Zu deiner anderen Frage:
Ich nehme Integer für Bools. :D

Re: Variable als Unsigned byte?

Verfasst: 03.08.2016 19:53
von ts-soft
DarkSoul hat geschrieben:Ascii wird aber ab 5.50 nicht mehr unterstützt. :?
Der Zeichensatz (die Codierung) wird nicht mehr unterstützt, hat aber rein gar nichts mit dem Variablen-Typ Ascii (*.a) zu tun!

Ansonsten, Du bist zu geizig. Integer ist der schnellste Datentyp und Speichersparen in so kleinen Dimensionen ist vielleicht auf einem
8-Bit Atari oder Sinclair erforderlich, bringt auf einem PC aber gar nichts. Datentypen, anders als Integer, normalerweise nur für Floats,
Double, Strings und in Strukturen/Interfaces.

// Nic war wieder schneller :mrgreen:

Re: Variable als Unsigned byte?

Verfasst: 03.08.2016 20:17
von DarkSoul
Ich habe es schon getestet. Ich wollte mich da nur absichern. Hätte ja sein können, dass .a nur noch zufällig funktioniert. 8)
Ansonsten, Du bist zu geizig. Integer ist der schnellste Datentyp...
Gibt es einen Beweis über die Geschwindigkeit? :mrgreen:

Bei größeren Arrays macht es imho einen größeren Unterschied (z.B. PCM-Daten)

Re: Variable als Unsigned byte?

Verfasst: 03.08.2016 20:25
von NicTheQuick
Die CPU ist schneller einen Integer aus dem Cache zu holen und gegen 0 zu prüfen als einen 8-Bit-Wert aus den 32/64-Bit Registern zu lesen und dann zusammen mit einem bitweisen AND gegen Null zu prüfen.

Ein CPU-Cache hat als kleinste Einheit normalerweise die Architektur-bedingte Wortgröße. Bei 32-Bit-CPUs also 32 Bit und bei 64-Bit-CPUs eben 64 Bit. Und genauso groß sind auch die Register, auf denen sie arbeitet. Wenn du jetzt eine 8-Bit-Variable in einem 64-Bit-Register gespeichert hast und du willst wissen, ob ein Bit in der Variable gesetzt ist, muss die CPU den 64-Bit mit der 8-Bit-Maske verrechnen, weil das zunächst der gewünschte Datentyp ist, und dann noch mit dem Bit verUNDen, das du testen willst. Das kostet mehr Zeit als gleich die 64 Bit gegen 0 oder sonst was zu testen. Bei 2 MB großen L3-Caches oder mehr heutzutage, sind da ein paar Bools nicht der Rede wert.

Möchtest du aber ganze Bit-Gruppen einer Funktion übergeben, lohnt es sich eventuell trotzdem mehrere Bits in einen Integer zu stecken. Dann ist der Funktionsaufruf schneller.

Re: Variable als Unsigned byte?

Verfasst: 03.08.2016 20:39
von DarkSoul
Ist das wirklich so? Für das Byte muss ja nicht unbedingt ganzes Register genommen werden. Es kann doch z.B. in dem einem Fall EAX/RAX und in dem anderen AL verwendet werden.

Re: Variable als Unsigned byte?

Verfasst: 03.08.2016 20:59
von mk-soft
Auf jedenfalls mehr Code da der 8bit Wert noch gefiltert werden muss.

ASM Auszug

Code: Alles auswählen

; 
; Global r1.a
; Global r2.i
; 
; 
; 
; r1 = foo1()
  CALL  _Procedure0
  MOV    rax,rax
  PUSH   rax
  POP    rax
  MOV    byte [v_r1],al
; r2 = foo2()
  CALL  _Procedure2
  MOV    qword [v_r2],rax
; 
; 
_PB_EOP:
_PB_EOP_NoValue:
  CALL  _PB_EndFunctions
  MOV    rsp,[PB_InitialStackValue]
  MOV    rax,[PB_ExitCode]
  RET
_PB_EndFunctions:
  SUB    rsp,40
  ADD    rsp,40
  RET

; Procedure.a foo1()
_Procedure0:
%define PS0 64
  XOR    rax,rax
  PUSH   rax
  PUSH   rax
  SUB    rsp,40
; Protected result.a
; a = 1
  MOV    qword [rsp+48],1
; ProcedureReturn a
  MOV    rax,qword [rsp+48]
  MOVZX  rax,al
  JMP   _EndProcedure1
; EndProcedure
_EndProcedureZero1:
  XOR    rax,rax
_EndProcedure1:
  ADD    rsp,56
  RET
; Procedure.i foo2()
_Procedure2:
%define PS2 64
  XOR    rax,rax
  PUSH   rax
  PUSH   rax
  SUB    rsp,40
; Protected result.i
; i = 1
  MOV    qword [rsp+48],1
; ProcedureReturn i
  MOV    rax,qword [rsp+48]
  JMP   _EndProcedure3
; EndProcedure
_EndProcedureZero3:
  XOR    rax,rax
_EndProcedure3:
  ADD    rsp,56
  RET