2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
6 #include "mathieeesingtrans_intern.h"
10 Calculate square root of IEEE single precision number
13 IEEE single precision number
18 overflow : square root could not be calculated
31 First check for a zero and a negative argument and take
35 Exponent is an odd number:
36 y = ( M*2 ) * 2^ (E-1)
37 Now E' = E-1 is an even number and
38 -> sqrt(y) = sqrt(M) * sqrt(2) * sqrt (2^E')
39 = sqrt(M) * sqrt(2) * 2^(E'/2)
41 = sqrt(M) * sqrt(2) * 2^(E'/2)
42 = sqrt(M) * 1/sqrt(2) * 2^(1+(E'/2))
43 = sqrt(M/2) * 2^(1+(E'/2))
46 Exponent is an even number:
47 -> sqrt(y) = sqrt(M) * sqrt (2^E) =
50 Now calculate the square root of the mantisse.
51 The following algorithm calculates the square of a number + delta
52 and compares it to the mantisse. If the square of that number +
53 delta is less than the mantisse then keep that number + delta.
54 Otherwise calculate a lower offset and try again.
55 Start out with number = 0;
62 if ( (Root + 2^Exponent)^2 < Mantisse)
66 until you`re happy with the accuracy
72 AROS_LH1(float, IEEESPSqrt
,
73 AROS_LHA(float, y
, D0
),
74 struct Library
*, MathIeeeSingTransBase
, 16, MathIeeeSingTrans
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 /* we can calculate the square-root now! */
97 TargetMantisse
= ((y
& IEEESPMantisse_Mask
) | 0x00800000) << 8;
101 /* TargetMantisse = TargetMantisse / 2; */
102 TargetMantisse
>>= 1;
103 Exponent
= ((y
>> 1) & IEEESPExponent_Mask
) + 0x20000000;
107 Exponent
= ((y
>> 1) & IEEESPExponent_Mask
) + 0x1f800000;
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
);
122 X = (Res+Delta)^2 = Res^2 + 2*Res*Delta + Delta^2
124 X
= ResSquared
+ (Res
>> z
) + (Delta
>> ++z
);
125 if (X
<= TargetMantisse
)
132 /* an adjustment for precision
134 if ((char) Res
< 0) Res
+= 0x100;
137 Res
&= IEEESPMantisse_Mask
;