Вот как для двумерного вектора оптимизировали в Delphi, причём описан код и ассемблерные команды тоже, для быстроты; может, пригодится:
Код:
function Hypot(const X, Y: Extended): Extended;
{ formula: Sqrt(X*X + Y*Y)
implemented as: |Y|*Sqrt(1+Sqr(X/Y)), |X| < |Y| for greater precision
var
Temp: Extended;
begin
X := Abs(X);
Y := Abs(Y);
if X > Y then
begin
Temp := X;
X := Y;
Y := Temp;
end;
if X = 0 then
Result := Y
else // Y > X, X <> 0, so Y > 0
Result := Y * Sqrt(1 + Sqr(X/Y));
end;
}
asm
FLD Y
FABS
FLD X
FABS
FCOM
FNSTSW AX
TEST AH,$45
JNZ @@1 // if ST > ST(1) then swap
FXCH ST(1) // put larger number in ST(1)
@@1: FLDZ
FCOMP
FNSTSW AX
TEST AH,$40 // if ST = 0, return ST(1)
JZ @@2
FSTP ST // eat ST(0)
JMP @@3
@@2: FDIV ST,ST(1) // ST := ST / ST(1)
FMUL ST,ST // ST := ST * ST
FLD1
FADD // ST := ST + 1
FSQRT // ST := Sqrt(ST)
FMUL // ST(1) := ST * ST(1); Pop ST
@@3: FWAIT
end;
Формула приведена так:
- уменьшается кол-во возведений в квадрат на 1.
Очевидно, можно что-то и в этом духе сделать:
, но это наверно хуже будет, наоборот, чем для двумерного случая - теперь слишком много делений. Но двумерная формула точно лучше работает