2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
6 #include "mathtrans_intern.h"
10 Calculate square root of ffp number
13 Motorola fast floating point number
18 overflow : square root could not be calculated
31 First check for a zero and a negative argument and take
35 If exponent is an odd number:
37 fnum = ( M*2 ) * 2^ (E-1)
38 Now E' = E-1 is an even number and
39 -> sqrt(fnum) = sqrt(M) * sqrt(2) * sqrt (2^E')
40 = sqrt(M) * sqrt(2) * 2^(E'/2)
42 = sqrt(M) * sqrt(2) * 2^(E'/2)
43 = sqrt(M) * 1/sqrt(2) * 2^(1+(E'/2))
44 = sqrt(M/2) * 2^(1+(E'/2))
48 If Exponent is an even number:
50 -> sqrt(fnum) = sqrt(M) * sqrt (2^E) =
54 Now calculate the square root of the mantisse.
55 The following algorithm calculates the square of a number + delta
56 and compares it to the mantisse. If the square of that number +
57 delta is less than the mantisse then keep that number + delta.
58 Otherwise calculate a lower delta and try again.
59 Start out with number = 0;
67 if ( ( Root + 2^Exponent ) ^2 < Mantisse)
71 until you`re happy with the accuracy
78 AROS_LH1(float, SPSqrt
,
79 AROS_LHA(float, fnum1
, D0
),
80 struct Library
*, MathTransBase
, 16, MathTrans
85 ULONG Res
, ResSquared
, Delta
, X
, TargetMantisse
;
91 SetSR(Zero_Bit
, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
94 /* is fnum negative */
97 SetSR(Overflow_Bit
, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
101 /* let us calculate the square-root now! */
103 TargetMantisse
= ((ULONG
)fnum1
& FFPMantisse_Mask
);
107 /* TargetMantisse = TargetMantisse / 2; */
108 TargetMantisse
>>= 1;
109 Exponent
= ((BYTE
)fnum1
>> 1) + 0x21;
113 Exponent
= ((BYTE
)fnum1
>> 1) + 0x20;
121 this calculates the sqrt of the mantisse. It`s short, isn`t it?
122 Delta starts out with 0.5, then 0.25, 0.125 etc.
124 while (ResSquared
!= TargetMantisse
&& z
< 25)
126 Delta
= (0x80000000 >> z
);
129 = Res^2 + 2*Res*Delta + Delta^2
131 X
= ResSquared
+ (Res
>> z
) + (Delta
>> (z
+1));
133 if (X
<= TargetMantisse
)
140 /* an adjustment for precision */
141 if ((char) Res
< 0) Res
+= 0x100;
143 Res
&= FFPMantisse_Mask
;