amath
1.8.5
Simple command line calculator
|
Square root function. More...
#include "prim.h"
Go to the source code of this file.
Functions | |
double | sqrt (double x) |
Square root function. More... | |
Variables | |
static const double | one = 1.0 |
static const double | tiny = 1.0e-300 |
Square root function.
Definition in file sqrt.c.
double sqrt | ( | double | x | ) |
Square root function.
Method: Bit by bit method using integer arithmetic. (Slow, but portable) 1. Normalization Scale x to y in [1,4) with even powers of 2: find an integer k such that 1 <= (y=x*2^(2k)) < 4, then sqrt(x) = 2^k * sqrt(y) 2. Bit by bit computation Let q = sqrt(y) truncated to i bit after binary point (q = 1), i 0 i+1 2 s = 2*q , and y = 2 * ( y - q ). (1) i i i i
To compute q from q , one checks whether i+1 i-(i+1) 2(q + 2 ) <= y. (2) i -(i+1) If (2) is false, then q = q ; otherwise q = q + 2 . i+1 i i+1 i
With some algebric manipulation, it is not difficult to see that (2) is equivalent to -(i+1) s + 2 <= y (3) i i
The advantage of (3) is that s and y can be computed by i i the following recurrence formula: if (3) is false
s = s , y = y ; (4) i+1 i i+1 i
otherwise, -i -(i+1) s = s + 2 , y = y - s - 2 (5) i+1 i i+1 i i
One may easily use induction to prove (4) and (5). Note. Since the left hand side of (3) contain only i+2 bits, it does not necessary to do a full (53-bit) comparison in (3). 3. Final rounding After generating the 53 bits result, we compute one more bit. Together with the remainder, we can decide whether the result is exact, bigger than 1/2ulp, or less than 1/2ulp (it will never equal to 1/2ulp). The rounding mode can be detected by checking whether huge + tiny is equal to huge, and whether huge - tiny is equal to huge for some floating point number "huge" and "tiny".
Special cases: sqrt(+-0) = +-0 ... exact sqrt(inf) = inf sqrt(-ve) = NaN ... with invalid signal sqrt(NaN) = NaN ... with invalid signal for signaling NaN
Definition at line 119 of file sqrt.c.
Referenced by acos(), acosh(), acsch(), acvs(), aexs(), ahv(), ahvc(), asech(), asin(), asinh(), aver(), csqrt(), hypot(), pow(), sec(), and RealNumber::SquareRoot().