![]() |
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 |
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); |
Re: IsPowerOfTwo
Zitat:
|
Re: IsPowerOfTwo
Zitat:
dann also > wieder rein und Abs raus :nerd:
Delphi-Quellcode:
Result := (i > 0) and (i and Pred(i) = 0);
|
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:
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.
function IsPowerOfTwo(Value: Cardinal): Boolean; assembler;
asm LEA EDX, EAX -1 AND EAX, EDX SETZ AL end; Deine BSF/BSR Opcodes sind "arsch langsam" ;) Gruß Hagen |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:20 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