![]() |
![]() |
|||||||
Er is overeenkomst met de vierkantswortel. [ziehier]. Als N = root3 + rest, dan levert het programma de waarde root en de rest.
Theorie Beschouw N als groepjes van 3 bits, geteld van rechts.[ab]2 = 2a + b (2a+b)3 = 8a3 + 12a2 + 6ab2 + b3. Bij de start is a=0 and "1" wordt afgetrokken van het rechter bit van het hoogste groepje (van 3) in N. Dan a=1, N is verminderd met 8a3 = [1000]2. Nu moet bit b gevonden worden: b=1 als 12a2b + 6ab2 + b3 van N kan worden afgetrokken. Dat levert [a1]2 als (b=1) of [a0]2 als (b=0). Dus, om het volgende bit (b) te vinden moet steeds 12a2b + 6ab2 + b3 van N worden afgetrokken. omdat b=1 is deze aftrekker : 12a2 + 6a + 1 = [a0]([a0] + 1)*3 + 1. Opmerking: [a0]2 = 2a. Elke poging levert een nieuw bit op van a. In geval van 30 bit getallen moeten bovenstaande stappen 10 keer worden herhaald. De derdemachts wortel is maximaal 10 bits groot. Opmerking: Derdemachts wortels kunnen ook uit negatieve getallen worden getrokken. Het programma
function CubeRoot(N : longInt; var rem : longInt) : smallInt;
// -1,073,741,823 <= N <= 1,073,741,823
//return integer cube root of N and remainder rem
const max = 1073741824;
var NX,sub,r2 : longInt;
root : word;
p : shortInt;
neg : boolean;
begin
if (N <= -max) or (N >= max) then
begin
result := 0;
rem := N;
exit;
end;
if N < 0 then begin
N := -N;
neg := true;
end else neg := false;
p := 30;
root := 0;
repeat
r2 := root shl 1;
sub := r2*(r2+1)*3+1;
sub := sub shl p;
root := root shl 1;
NX := N - sub;
if NX >= 0 then
begin
N := NX;
root := root or 1;
end;
p := p - 3;
until p < 0;
if neg then begin
root := -root;
N := -N;
end;
result := root;
rem := N;
end;
procedure TForm1.GoBtnClick(Sender: TObject);
var N,rem : longInt;
root : smallInt;
begin
if length(numberEdit.Text) = 0 then numberEdit.Text := '0';
N := strtoInt(numberEdit.Text);
root := cubeRoot(N,rem);
rootLabel.Caption := inttostr(root);
remainderlabel.Caption := inttostr(rem);
end;
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
var OK,mt : boolean;
begin
OK := false;
with numberEdit do
begin
mt := length(text) = 0;
case key of
#8 : OK := true;
'1'..'9' : OK := true;
'0' : OK := not(mt);
'$' : OK := mt;
'a'..'f' : OK := text[1] = '$';
'-' : OK := mt;
end;
if OK = false then key := #0;
end;
end;
end.
|
||||||||
![]() |
![]() |