![]() |
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:
Gruß
//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; Wolfgang |
Re: IsPowerOfN
Delphi-Quellcode:
:duck:
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; 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) |
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...
|
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; |
Re: IsPowerOfN
sollte das Ergebnis von Ln nicht immer größer als 0 sein, wenn auch der übergebene Wert größer 0 ist?
|
Re: IsPowerOfN
Nein, Log(1) ist immer exakt Null, zu jeder Basis.
Gruß Wolfgang |
Re: IsPowerOfN
Zitat:
Hast Du grad keine Delphi zur Hand? ln(0.5) = -0.6931471805599453094172321215! |
Re: IsPowerOfN
Richtig, unter 1 wird der Logarithmus negativ bis - unendlich,
bei Null crashed es Gruß Wolfgang |
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:
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?
// Alzaimar - Delphi - PRAXiS
Function AddNumbers (A,B : Extended) : Extended; Begin Result := A + B End; |
Re: IsPowerOfN
Zitat:
Zitat:
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 19:31 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