Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi IsPowerOfN (https://www.delphipraxis.net/142189-ispowerofn.html)

Wolfgang Mix 23. Okt 2009 13:02


IsPowerOfN
 
Des öfteren möchte man testen, ob eine ganze Zahl (>=1) eine ganze Potenz von n (>=1) ist,
zb. 1,3,9,27,81,243 für n=3 usw. Die beiden nachfolgenden Funktionen erledigen das.

Anmerkung: Bei sehr großen Zahlen werden fehlerhafte Werte zurückgegeben.


Delphi-Quellcode:
//Wolfgang Mix - Delphi - PRAXiS
function LgX(base, number: Double): Double; //inline;
begin
  if (base <= 0.0) or (number <= 0.0) then
    System.Error(reInvalidOp);
  Result := Ln(number) / Ln(base); //plattformunabhängig
end;

//Wolfgang Mix - Delphi - PRAXiS
function IsPowerOfX(base, number: Double): Boolean;
begin
  Result := Frac(LgX(base, number)) < 1e-9;
end;
Gruß

Wolfgang

himitsu 23. Okt 2009 13:08

Re: IsPowerOfN
 
Delphi-Quellcode:
function LgX(base, number: Double): Double; //inline;
begin
  if (base <= 0.0) or (number <= 0.0) then
    System.Error(reInvalidOp);
  Result := Ln(number) / Ln(base);
end;

function IsPowerOfX(base, number: Double): Boolean; //inline;
begin
  Result := Frac(LgX(base, number)) < 1e-9;
end;
:duck:


Warum ich die Parameterprüfung verschoben hab:
Damit ein einzeln genutztes LgX auch geprüft wird und IsPowerOfX braucht diese nicht, da dort durch LgX gleich mitgeprüft wird,


PS: Das Inline kann man übrigens bei neueren Delphis "aktivieren", dann wird keine eigenständige Funktion erstellt, sondern der Code direkt an Ort und Stelle als Inline-Code eingefügt.
(ältere Versionen kennen den Befehl leider nicht ... drum auskommentiert)

OldGrumpy 23. Okt 2009 14:21

Re: IsPowerOfN
 
Habt ihr auch mal getestet ob die Funktion bei sehr großen Zahlen nicht "aus Versehen" ein fälschlich positives Ergebnis liefert? Da bei Fließkommarechnungen immer Unschärfen auftreten, habe ich da etwas Bauchweh mit dem "kleiner 1e-9". Allerdings habe ich mir jetzt nicht die Mühe gemacht, die Grenzen der Wertebereiche der verwendeten Datentypen abzuklopfen. Notfalls müsste man mit Int64 oder BigInt, Div und Modulo arbeiten um sicherzugehen...

gammatester 23. Okt 2009 17:24

Re: IsPowerOfN
 
Leider wiedermal ziemlich ungetestet und falsch. Neben OldGrumpys Bedenken, hier ein fetter Bug: Jede Zahl number > 1 ist eine Potenz zu base < 1! Warum? Weil ln(number) > 0 und ln(base) < 0 also lgx(base, number) < 0 < 1e-9. Also ist mindestens ein abs dringend erforderlich.

Delphi-Quellcode:
function IsPowerOfX(base, number: double): boolean;
begin
  result := abs(frac(lgx(base, number))) < 1e-9;
end;

himitsu 23. Okt 2009 17:28

Re: IsPowerOfN
 
sollte das Ergebnis von Ln nicht immer größer als 0 sein, wenn auch der übergebene Wert größer 0 ist?

Wolfgang Mix 23. Okt 2009 18:20

Re: IsPowerOfN
 
Nein, Log(1) ist immer exakt Null, zu jeder Basis.

Gruß

Wolfgang

gammatester 23. Okt 2009 18:21

Re: IsPowerOfN
 
Zitat:

Zitat von himitsu
sollte das Ergebnis von Ln nicht immer größer als 0 sein, wenn auch der übergebene Wert größer 0 ist?

???
Hast Du grad keine Delphi zur Hand? ln(0.5) = -0.6931471805599453094172321215!

Wolfgang Mix 23. Okt 2009 18:35

Re: IsPowerOfN
 
Richtig, unter 1 wird der Logarithmus negativ bis - unendlich,
bei Null crashed es

Gruß

Wolfgang

alzaimar 23. Okt 2009 19:30

Re: IsPowerOfN
 
Entschuldigt, aber wo ist der Mehrwert? Das ist Schulmathematik bzw. trivial. Mich erinnert das an die Funktion, die zwei Zahlen addiert:
Delphi-Quellcode:
// Alzaimar - Delphi - PRAXiS
Function AddNumbers (A,B : Extended) : Extended;
Begin
  Result := A + B
End;
Und anstatt LgX sollte/könnte man auch die Funktion LogN aus der Unit Math nehmen. Weiterhin ist mir der Mehrwert der präventiven Prüfung der Parameter ggü. einem einfachen An-die-Wand-fahren-lassen nicht klar bzw. bedarf einer Erklärung: Was passiert, wenn man die Prüfung weglässt?

gammatester 23. Okt 2009 19:50

Re: IsPowerOfN
 
Zitat:

Zitat von alzaimar
Entschuldigt, aber wo ist der Mehrwert? Das ist Schulmathematik bzw. trivial.

Zitat:

Zitat von alzaimar
Und anstatt LgX sollte/könnte man auch die Funktion LogN aus der Unit Math nehmen. Weiterhin ist mir der Mehrwert der präventiven Prüfung der Parameter ggü. einem einfachen An-die-Wand-fahren-lassen nicht klar bzw. bedarf einer Erklärung: Was passiert, wenn man die Prüfung weglässt?

Voll einverstanden. Eine ähnliche Diskussion hatten wir schon im Vorgängerthread zu lgx bzw. logn. Dort hatte ich auch auf math.logn verwiesen, und andere hatten den Nährwert bezweifelt.

Das hält manche allerdings nicht davon ab, völlig triviale matmematische Aussagen in schlechte und falsche Programme umzusetzen.

Wäre ja irgendwo kein Problem, wenn's nicht als Beitrag zu Codelibrary vertrieben würde.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:38 Uhr.
Seite 1 von 3  1 23      

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