2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
6 #include "mathtrans_intern.h"
8 /*****************************************************************************
12 AROS_LH1(float, SPSqrt
,
15 AROS_LHA(float, fnum1
, D0
),
18 struct Library
*, MathTransBase
, 16, MathTrans
)
21 Calculate square root of ffp number
26 Motorola fast floating point number
31 overflow : square root could not be calculated
37 First check for a zero and a negative argument and take
41 If exponent is an odd number:
43 fnum = ( M*2 ) * 2^ (E-1)
44 Now E' = E-1 is an even number and
45 -> sqrt(fnum) = sqrt(M) * sqrt(2) * sqrt (2^E')
46 = sqrt(M) * sqrt(2) * 2^(E'/2)
48 = sqrt(M) * sqrt(2) * 2^(E'/2)
49 = sqrt(M) * 1/sqrt(2) * 2^(1+(E'/2))
50 = sqrt(M/2) * 2^(1+(E'/2))
53 If Exponent is an even number:
54 -> sqrt(fnum) = sqrt(M) * sqrt (2^E) =
57 Now calculate the square root of the mantisse.
58 The following algorithm calculates the square of a number + delta
59 and compares it to the mantisse. If the square of that number +
60 delta is less than the mantisse then keep that number + delta.
61 Otherwise calculate a lower delta and try again.
62 Start out with number = 0;
69 if ( ( Root + 2^Exponent ) ^2 < Mantisse)
73 until you`re happy with the accuracy
75 *****************************************************************************/
79 ULONG Res
, ResSquared
, Delta
, X
, TargetMantisse
;
85 SetSR(Zero_Bit
, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
88 /* is fnum negative */
91 SetSR(Overflow_Bit
, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
95 /* let us calculate the square-root now! */
97 TargetMantisse
= ((ULONG
)fnum1
& FFPMantisse_Mask
);
101 /* TargetMantisse = TargetMantisse / 2; */
102 TargetMantisse
>>= 1;
103 Exponent
= ((BYTE
)fnum1
>> 1) + 0x21;
107 Exponent
= ((BYTE
)fnum1
>> 1) + 0x20;
115 this calculates the sqrt of the mantisse. It`s short, isn`t it?
116 Delta starts out with 0.5, then 0.25, 0.125 etc.
118 while (ResSquared
!= TargetMantisse
&& z
< 25)
120 Delta
= (0x80000000 >> z
);
123 = Res^2 + 2*Res*Delta + Delta^2
125 X
= ResSquared
+ (Res
>> z
) + (Delta
>> (z
+1));
127 if (X
<= TargetMantisse
)
134 /* an adjustment for precision */
135 if ((char) Res
< 0) Res
+= 0x100;
137 Res
&= FFPMantisse_Mask
;