Super, allerings gäbe es einige Verbesserungen:
1.) Decimals als Int64 ist utopisch groß, schon bei Decimals: Cardinal dürftest du die Speichergrenzen fast aller Rechner sprengen
2.) Alle Interfaces -> IInteger sollten entweder als const oder var übergeben werden, in deinem Falle ist R: IInteger wenig sinnvoll.
3.) Man kann NMul(R1, R1) benutzen, sauberer wäre aber NSqr(R1). Zum Glück überprüft NMul(R1, R1) ob beide Parameter identisch ist und nutzt intern sowieso NSqr(R1), es gibt also keinen Unterschied. Wäre dies NICHT so dann würde NSqr(R1) ca. 1.5 mal schneller sein als NMul(R1, R1).
4.) die Parameterreihenfolge sollte angepasst werden ans
DEC, d.h. zuerst Ausgabeparameter dann readonly Eingabeparameter
Es sähe dann so aus:
Delphi-Quellcode:
procedure NRoot(var R: IInteger; const A: IInteger; Root,Digits: Integer; Base: TBase = 10); overload;
// R = A^(1/Root) * Base^Digits
resourcestring
sNRoot1 = 'NRoot(), invalid paramater Root, must be >= 2';
sNRoot2 = 'NRoot(), invalid paramater Digits, must be >= 0';
var
T: IInteger;
begin
if Root < 2 then NRaise(@sNRoot1);
if Digits < 0 then NRaise(@sNRoot2);
NPow(T, Base, Digits);
NPow(T, Root);
NMul(T, A); // A ist verbaut worden, nun können wir sicher R überschreiben
NRoot(R, T, Root); // somit müssen R und A nicht distinct sein, ein Aufruf wie
end; // NRoot(R, R, 2, 1000) wäre legal. (Bullet proof)
Man muß sich nun vorstellen was es bedeutet wenn Digits/Decimals > MaxInt wäre.
Im besten Falle würde man 2^0.5 * 2^2^2^31 rechnen ! Alleine schon 2^2^31 = 2^MaxInt benötigte also 2 Gigabytes an Speicher. D.h. wenn Digits/Decimals größer MaxInt wird benötigt man weit weit mehr als Terabytes Rechner. Mal abgesehen von der nötigen Rechenzeit.
Es macht also keinen Sinn Digits/Decimals größer als Integer zu deklarieren.
Allerdings macht es dagegen Sinn die Zahlenbasis "Base", die Wurzel Root selber und den Wert A von dem man die Wurzel berechnen will zu übergeben.
Mit obigen Code würde man zB. mit NRoot(R, NInt(15), 2, 1000, 8); die 2'te Wurzel aus 15 zu 1000 Oktalen Nachkommastellen berechnen. Also 15^(1/2) * 8^1000.
Mit NRoot(R, NTwo, 2, 1000, 10); demzufolge 1000 Nachkommastellen von Quadratwurzel aus 2, und NRoot(R, NTwo, 3, 1000, 10); die 3'te Wurzel aus 2 mit 1000 Nachkommastellen.
Man wird bei Wurzeln > 2 feststellen das der Quadratwurzel Algorithmus um Längen schneller ist als zu höherwertigen Wurzelbasen.
Gruß Hagen