Maximum/Minimum(Byte)

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Maximum/Minimum(Byte)

Beitrag von cxAlex »

Code zu berechnen wie viele ganzzahlige Werte man in n - Bytes stopfen kann, für signed und unsigned. Lustig wenn jemand schon immer mal wissen wollte was er maximal in eine 3/5/6/7 - Byte Variable stopfen könnte, sonst eher sinnlos (Hab grad mit den Shift-Operatoren rumgespielt ^^)

Code: Alles auswählen

Macro Bool(Arg)
  ((Arg) Or #Null)
EndMacro

Procedure.q MaximumValue(Bytes, Signed = #True)
  Protected Val.q, Bits, i
  Bits = Bytes*8-(1 + 1*Bool(Signed))
  For i = 0 To Bits
    Val + (1<<i)
  Next
  ProcedureReturn Val
EndProcedure

Procedure.q MinimumValue(Bytes)
  Protected Val.q, Bits, i
  Bits = Bytes*8-2
  For i = 0 To Bits
    Val + (1<<i)
  Next
  If Val
    Val + 1
  EndIf
  ProcedureReturn Val*-1
EndProcedure

Debug MaximumValue(SizeOf(Byte))
Debug MaximumValue(SizeOf(Long))
Debug MaximumValue(SizeOf(Quad))
Debug MinimumValue(SizeOf(Byte))
Debug MinimumValue(SizeOf(Long))
Debug MinimumValue(SizeOf(Quad))
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Little John

Re: Maximum/Minimum(Byte)

Beitrag von Little John »

cxAlex hat geschrieben:(Hab grad mit den Shift-Operatoren rumgespielt ^^)
Das geht einfacher ohne Shift-Operatoren in For-Schleifen. <)

Code: Alles auswählen

EnableExplicit

Procedure.q MinValue (bytes, signed=#True)
   Protected ret.q

   If signed
      ret = -Pow(2, bytes*8-1)
   Else
      ret = 0
   EndIf
   ProcedureReturn ret
EndProcedure

Procedure.q MaxValue (bytes, signed=#True)
   Protected ret.q

   If signed
      ret = Pow(2, bytes*8-1)
   Else
      ret = Pow(2, bytes*8)
   EndIf
   ProcedureReturn ret - 1
EndProcedure


;-- Demo
Debug MinValue(SizeOf(Byte))
Debug MaxValue(SizeOf(Byte))
Debug MinValue(SizeOf(Byte), #False)
Debug MaxValue(SizeOf(Byte), #False)
Debug "------------------"
Debug MinValue(SizeOf(Word))
Debug MaxValue(SizeOf(Word))
Debug MinValue(SizeOf(Word), #False)
Debug MaxValue(SizeOf(Word), #False)
Debug "------------------"
Debug MinValue(SizeOf(Long))
Debug MaxValue(SizeOf(Long))
Debug MinValue(SizeOf(Long), #False)
Debug MaxValue(SizeOf(Long), #False)
Debug "------------------"
Debug MinValue(SizeOf(Quad))
Debug MaxValue(SizeOf(Quad))
Debug MinValue(SizeOf(Quad), #False)
Debug MaxValue(SizeOf(Quad), #False)
Gruß, Little John
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Beitrag von cxAlex »

Aber meine Methode ist sicher schneller :mrgreen:.
(in dem Fall komplett sinnlos ^^)
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Little John

Beitrag von Little John »

cxAlex hat geschrieben:Aber meine Methode ist sicher schneller :mrgreen:.
(in dem Fall komplett sinnlos ^^)
a) Sicher ist das keineswegs, das wäre erst noch zu beweisen.
b) Wenn's wirklich schnell gehen soll, schreibt man das am besten in ASM. Dabei lässt sich

Code: Alles auswählen

Pow(2, x)
einfach durch eine entspr. Bit-Operation ersetzen.

Sorry, aber das hier ist einfach kein sinnvoller Tip oder Trick für Shift-Operationen.

Gruß, Little John
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Beitrag von cxAlex »

Das das ganze eigentlich keinen Sinn hat hab ich aber schon in meinem 1. Post geschrieben....
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

Little John hat geschrieben:b) Wenn's wirklich schnell gehen soll, schreibt man das am besten in ASM. Dabei lässt sich

Code: Alles auswählen

Pow(2, x)
einfach durch eine entspr. Bit-Operation ersetzen.
Left Shift ist eine dieser Bit-Operationen. :freak:
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Little John

Beitrag von Little John »

DarkDragon hat geschrieben:Left Shift ist eine dieser Bit-Operationen. :freak:
Ich hatte an BTS ("bit set") gedacht. Aber Du hast natürlich Recht, Left Shift geht auch.
Ich würde es dann allerdings nicht in einer Schleife verwenden.

Und auch in normalem PB-Code ohne ASM wird hierfür keine Schleife mit Shift-Operationen benötigt.
Wem Pow() zu langsam ist, der kann mit

Code: Alles auswählen

Macro Power2 (_x_)
   (1 << (_x_))
EndMacro
in meinem obigen Code

Code: Alles auswählen

Pow(2, i) 
durch

Code: Alles auswählen

Power2(i) 
ersetzen.

Gruß, Little John
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

Little John hat geschrieben:
DarkDragon hat geschrieben:Left Shift ist eine dieser Bit-Operationen. :freak:
Ich hatte an BTS ("bit set") gedacht. Aber Du hast natürlich Recht, Left Shift geht auch.
Hmm ich dachte immer, dass es sowas auf X86 und X64 nicht gibt, weil ich hier schon desöfteren vor Jahren gelesen hab, dass es keine Bitadressierung gibt auf diesen Architekturen. Anscheinend gibts die ja doch. Ich kenne das vom 8051 aber da hieß es SETB.

Klar, Schleifen sind blöd wegen dem Prefetching.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Little John

Beitrag von Little John »

Das kann z.B. so eingesetzt werden:

Code: Alles auswählen

Procedure Power2 (exponent)
   ! xor  eax, eax
   ! mov  ecx, [p.v_exponent]
   ! bts  eax, ecx
   ProcedureReturn
EndProcedure

;-- Demo
For i = 0 To 10
   Debug Power2(i)
Next
Gruß, Little John
Antworten