AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Anzahl der Einträge in einem SET ermitteln
Thema durchsuchen
Ansicht
Themen-Optionen

Anzahl der Einträge in einem SET ermitteln

Ein Thema von Baeuerle · begonnen am 3. Sep 2008 · letzter Beitrag vom 8. Apr 2010
 
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.340 Beiträge
 
Delphi 12 Athens
 
#9

Re: Anzahl der Einträge in einem SET ermitteln

  Alt 8. Apr 2010, 12:14
Joar, also ich hatte/hab da auch grad ein kleines Problem.

Im Grunde hab ich "nur" 2 Register frei. (solange ich nicht extra noch ein paar Register-Werte kurzfristig auslagere, was ich aber eigentlich vermeiden wollte)
In EDX liegt der zu prüfende/zählende Wert und bei EAX sollen die Bits von EDX zuaddiert werden,
wobei EDX ruhig vernichtet werden kann.

Dieses geht ja leider nicht:
Delphi-Quellcode:
ADD EAX, BYTE PTR [@@Table + DL]
ADD EAX, BYTE PTR [@@Table + DH]
SHR EDX, 16
ADD EAX, BYTE PTR [@@Table + DL]
ADD EAX, BYTE PTR [@@Table + DH]


@@Table:
DB 0,1,1,2,1,2,2,3, 1,2,2,3,2,3,3,4, 1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5
DB 1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6
DB 1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6
DB 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7
DB 1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6
DB 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7
DB 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7
DB 3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7, 4,5,5,6,5,6,6,7, 5,6,6,7,6,7,7,8
Ein ADDZX, also sowas wie MOVZX, welches ein Byte ausließt und zu einem ganzen Register addiert, gibt es leider auch nicht, ebenso wie der Compiler nicht so gern die Byte-Registern arbeitet.
Ich müßte diesen Code also irgendwie so zerlegen, daß er die Bytes erstmal separiert und dann einzeln rechnetwerden,
aber da kann ich auch fast meinen aktuellen Code lassen, welcher einfach die Bits einzeln über eine SHIFT-Operation prüft.
Delphi-Quellcode:
TEST EDX, EDX // While EDX <> 0 do Begin
JZ @@Exit //
@@Loop: //
JNS @@NoInc // If Odd(EDX) Then
INC EAX // Inc(Result);
@@NoInc: //
SHL EDX, 1 // EDX := EDX shr 1;
JNZ @@Loop // End;
@@Exit:
Soooo oft wird dieser Code wohl nicht ausgeführt, als daß es sich lohnt ihn so extrem zu "optimieren", daß am Ende keiner mehr durchsieht, was da eigentlich gemacht wird.

PS: zu Code-Library -> Object-Pascal / Delphi-Language -> Datenbits effektiv zählen
Die ~200 zusätzlichen Bytes fallen in einer "normalen" Anwendung wohl nicht wirklich auf,
aber dafür würden etwa 50% der Speicher-/Rechenoperationen eingespart.
Delphi-Quellcode:
function CountBitsSet(P: Pointer; Count: Cardinal): Cardinal;
const
  lu : packed array[0..$FF] of Byte = (
    0,1,1,2,1,2,2,3, 1,2,2,3,2,3,3,4, 1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5,
    1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6,
    1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6,
    2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7,
    1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6,
    2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7,
    2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7,
    3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7, 4,5,5,6,5,6,6,7, 5,6,6,7,6,7,7,8);
begin
  Result := 0;
  while Count > 0 do
  begin
    Inc(Result, lu[PByte(P)^]);
    Inc(PByte(P));
    Dec(Count);
  end;
end;
Delphi-Quellcode:
function CountBitsSet(P: Pointer; Count: Cardinal): Cardinal;
const
  lu : packed array[0..$FF] of Byte = (
    0,1,1,2,1,2,2,3, 1,2,2,3,2,3,3,4, 1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5,
    1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6,
    1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6,
    2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7,
    1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6,
    2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7,
    2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7,
    3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7, 4,5,5,6,5,6,6,7, 5,6,6,7,6,7,7,8);
begin
  Result := 0;
  while Count > 0 do
  begin
    Dec(Count);
    Inc(Result, lu[(PByte(P) + Count)^]);
  end;
end;
Beide Funktionen sind etwa gleich "langsam", wobei Letztere aber im Test die Nase um eine Haareslänge voraus war.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:28 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz