Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Neuen Beitrag zur Code-Library hinzufügen (https://www.delphipraxis.net/33-neuen-beitrag-zur-code-library-hinzufuegen/)
-   -   Delphi IsPowerOfTwo (https://www.delphipraxis.net/133667-ispoweroftwo.html)

gammatester 7. Mai 2009 14:26

Re: IsPowerOfTwo
 
Zwei Anmerkungen:

1. In dem angeführten Code ist mM ein Rangecheck nicht nötig! Wo soll er denn zuschlagen, wenn i>0 ist?

2. Völlig überflüssig sind die abs()-Aufrufe, wenn i>0 ist.

Gammatester

himitsu 7. Mai 2009 14:37

Re: IsPowerOfTwo
 
2: das > war 'nen Copy&Paster-Fehlerchen :oops: und sollte ein <> sein

1: Abs(MinInt) = MaxInt+1 , also außerhalb des Wertebereichs, da der negative Bereich um 1 größer ist, also der Positive, weil die 0 im positiven Bit-Satz enthalten ist.

Delphi-Quellcode:
// ohne Rangeprobleme, da der Sonderfall von MinInt abgefangen wird
Result := (i = Low(Integer))
  or (i > 0) and (i and Pred(i) = 0)
  or (i < 0) and (-i and Pred(-i) = 0);

// mit Rangeproblem
Result := (i > 0) and (i and Pred(i) = 0)
  or (i < 0) and (-i and Pred(-i) = 0);

// mit Rangeproblem - verkürzt
Result := (i <> 0) and (i and Pred(Abs(i)) = 0);

3_of_8 7. Mai 2009 15:35

Re: IsPowerOfTwo
 
Zitat:

Zitat von himitsu
Zitat:

Zitat von 3_of_8
Funktioniert aber so nicht bei negativen Zahlen - da müsste man ein i>0 reintun.

ist klar, da durch die Dastellung oben alles 1 und unten alle Bits 0 sein müßten (siehe Aufbau des Zweierkomplements)

Mit Zweierkomplement hat das nichts zu tun - negative Zahlen können nunmal einfach keine Zweierpotenz sein, da 2^i>0 für alle reellen i. (Bei komplexen Exponenten sieht das wieder anders aus, aber darum gehts ja hier nicht.)

himitsu 7. Mai 2009 15:57

Re: IsPowerOfTwo
 
Zitat:

Zitat von 3_of_8
Mit Zweierkomplement hat das nichts zu tun - negative Zahlen können nunmal einfach keine Zweierpotenz sein, da 2^i>0 für alle reellen i. (Bei komplexen Exponenten sieht das wieder anders aus, aber darum gehts ja hier nicht.)

ach menno, so kann man sich auch verdenken :wall:

dann also > wieder rein und Abs raus :nerd:
Delphi-Quellcode:
Result := (i > 0) and (i and Pred(i) = 0);

negaH 16. Aug 2009 08:44

Re: IsPowerOfTwo
 
Davon abgesehen ist in meinem originalem Code der Parameter "Value" mit Absicht als Cardinal deklariert. Der kann garnicht < 0 werden, mal abgesehen davon das ältere Delphi Versionen den vorzeichenlosen Cardinal als vorzeichenbehafteten Integer interpretierten.

Wenn du ASM benutzen möchtest dann so

Delphi-Quellcode:
function IsPowerOfTwo(Value: Cardinal): Boolean; assembler;
asm
     LEA EDX, EAX -1
     AND EAX, EDX
     SETZ AL
end;
Diese Funktion dürfte die am schnellsten ausführbare auf heutigen Intel CPUs sein, also auch Branch frei. Allerdings wird der Wert 0 auch als Potenz von 2 betrachtet.

Deine BSF/BSR Opcodes sind "arsch langsam" ;)

Gruß Hagen


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:01 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz