2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
6 #include "mathieeesingtrans_intern.h"
8 /*****************************************************************************
12 AROS_LH1(float, IEEESPSqrt
,
15 AROS_LHA(float, y
, D0
),
18 struct Library
*, MathIeeeSingTransBase
, 16, MathIeeeSingTrans
)
21 Calculate square root of IEEE single precision number
26 IEEE single precision number
31 overflow : square root could not be calculated
37 First check for a zero and a negative argument and take
41 Exponent is an odd number:
42 y = ( M*2 ) * 2^ (E-1)
43 Now E' = E-1 is an even number and
44 -> sqrt(y) = sqrt(M) * sqrt(2) * sqrt (2^E')
45 = sqrt(M) * sqrt(2) * 2^(E'/2)
47 = sqrt(M) * sqrt(2) * 2^(E'/2)
48 = sqrt(M) * 1/sqrt(2) * 2^(1+(E'/2))
49 = sqrt(M/2) * 2^(1+(E'/2))
52 Exponent is an even number:
53 -> sqrt(y) = sqrt(M) * sqrt (2^E) =
56 Now calculate the square root of the mantisse.
57 The following algorithm calculates the square of a number + delta
58 and compares it to the mantisse. If the square of that number +
59 delta is less than the mantisse then keep that number + delta.
60 Otherwise calculate a lower offset and try again.
61 Start out with number = 0;
68 if ( (Root + 2^Exponent)^2 < Mantisse)
72 until you`re happy with the accuracy
74 *****************************************************************************/
78 ULONG Res
, ResSquared
, Delta
, X
, TargetMantisse
;
84 SetSR(Zero_Bit
, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
87 /* is fnum negative? */
90 SetSR(Overflow_Bit
, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
94 /* we can calculate the square-root now! */
96 TargetMantisse
= ((y
& IEEESPMantisse_Mask
) | 0x00800000) << 8;
100 /* TargetMantisse = TargetMantisse / 2; */
101 TargetMantisse
>>= 1;
102 Exponent
= ((y
>> 1) & IEEESPExponent_Mask
) + 0x20000000;
106 Exponent
= ((y
>> 1) & IEEESPExponent_Mask
) + 0x1f800000;
114 this calculates the sqrt of the mantisse. It`s short, isn`t it?
115 Delta starts out with 0.5, then 0.25, 0.125 etc.
117 while (ResSquared
!= TargetMantisse
&& z
< 25)
119 Delta
= (0x80000000 >> z
);
121 X = (Res+Delta)^2 = Res^2 + 2*Res*Delta + Delta^2
123 X
= ResSquared
+ (Res
>> z
) + (Delta
>> (z
+1));
125 if (X
<= TargetMantisse
)
132 /* an adjustment for precision
134 if ((char) Res
< 0) Res
+= 0x100;
137 Res
&= IEEESPMantisse_Mask
;