diff options
author | Jacques Garrigue <garrigue at math.nagoya-u.ac.jp> | 2002-04-18 07:00:34 +0000 |
---|---|---|
committer | Jacques Garrigue <garrigue at math.nagoya-u.ac.jp> | 2002-04-18 07:00:34 +0000 |
commit | 3447e059f033e7d59b4262fe869115aae20bcb85 (patch) | |
tree | ec3442ebc0940aefd4d6ab0e67dd88c08d5f5496 /stdlib/complex.ml | |
parent | 059d9fc181595b6cf7d2d1a6472eb97fce1fe86a (diff) | |
download | ocaml-poly_meth2.tar.gz |
merging poly_meth2poly_meth2
git-svn-id: http://caml.inria.fr/svn/ocaml/branches/poly_meth2@4692 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'stdlib/complex.ml')
-rw-r--r-- | stdlib/complex.ml | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/stdlib/complex.ml b/stdlib/complex.ml index fe2e0388d1..3095534bab 100644 --- a/stdlib/complex.ml +++ b/stdlib/complex.ml @@ -62,16 +62,21 @@ let arg x = atan2 x.im x.re let polar n a = { re = cos a *. n; im = sin a *. n } -let sqrt x = - (* Avoid cancellation in computing norm x + x.re - when x.re < 0 and x.im is small *) - if x.re >= 0.0 then begin - let r = sqrt(0.5 *. norm x +. 0.5 *. x.re) in - { re = r; im = if r = 0.0 then 0.0 else 0.5 *. x.im /. r } - end else begin - let s = sqrt(0.5 *. norm x -. 0.5 *. x.re) in - { re = if s = 0.0 then 0.0 else 0.5 *. abs_float x.im /. s; - im = if x.im >= 0.0 then s else -. s } +let sqrt x = + if x.re = 0.0 && x.im = 0.0 then { re = 0.0; im = 0.0 } + else begin + let r = abs_float x.re and i = abs_float x.im in + let w = + if r >= i then begin + let q = i /. r in + sqrt(r) *. sqrt(0.5 *. (1.0 +. sqrt(1.0 +. q *. q))) + end else begin + let q = r /. i in + sqrt(i) *. sqrt(0.5 *. (q +. sqrt(1.0 +. q *. q))) + end in + if x.re >= 0.0 + then { re = w; im = 0.5 *. x.im /. w } + else { re = 0.5 *. i /. w; im = if x.im >= 0.0 then w else -. w } end let exp x = |