Annotation of OpenXM_contrib/gmp/mpfr/hypot.c, Revision 1.1.1.1
1.1 ohara 1: /* mpfr_hypot -- Euclidean distance
2:
3: Copyright 2001, 2002 Free Software Foundation, Inc.
4:
5: This file is part of the MPFR Library.
6:
7: The MPFR Library is free software; you can redistribute it and/or modify
8: it under the terms of the GNU Lesser General Public License as published by
9: the Free Software Foundation; either version 2.1 of the License, or (at your
10: option) any later version.
11:
12: The MPFR Library is distributed in the hope that it will be useful, but
13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15: License for more details.
16:
17: You should have received a copy of the GNU Lesser General Public License
18: along with the MPFR Library; see the file COPYING.LIB. If not, write to
19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20: MA 02111-1307, USA. */
21:
22: #include <stdio.h>
23: #include <stdlib.h>
24: #include "gmp.h"
25: #include "gmp-impl.h"
26: #include "mpfr.h"
27: #include "mpfr-impl.h"
28:
29: /* The computation of hypot of x and y is done by
30:
31: hypot(x,y)= sqrt(x^2+y^2) = z
32: */
33:
34: int
35: mpfr_hypot (mpfr_ptr z, mpfr_srcptr x ,mpfr_srcptr y , mp_rnd_t rnd_mode)
36: {
37: int inexact;
38: /* Flag calcul exacte */
39: int not_exact=0;
40:
41: /* particular cases */
42:
43: if (MPFR_IS_NAN(x) || MPFR_IS_NAN(y))
44: {
45: MPFR_SET_NAN(z);
46: MPFR_RET_NAN;
47: }
48:
49: MPFR_CLEAR_NAN(z);
50:
51: if (MPFR_IS_INF(x) || MPFR_IS_INF(y))
52: {
53: MPFR_SET_INF(z);
54: MPFR_SET_POS(z);
55: MPFR_RET(0);
56: }
57:
58: MPFR_CLEAR_INF(z);
59:
60: if(MPFR_IS_ZERO(x))
61: return mpfr_abs (z, y, rnd_mode);
62:
63: if(MPFR_IS_ZERO(y))
64: return mpfr_abs (z, x, rnd_mode);
65:
66: /* General case */
67:
68: {
69: /* Declaration of the intermediary variable */
70: mpfr_t t, te,ti;
71: /* Declaration of the size variable */
72: mp_prec_t Nx = MPFR_PREC(x); /* Precision of input variable */
73: mp_prec_t Ny = MPFR_PREC(y); /* Precision of input variable */
74: mp_prec_t Nz = MPFR_PREC(z); /* Precision of input variable */
75:
76: int Nt; /* Precision of the intermediary variable */
77: long int err; /* Precision of error */
78:
79: /* compute the precision of intermediary variable */
80: Nt=MAX(MAX(Nx,Ny),Nz);
81:
82: /* compute the size of intermediary variable -- see algorithms.ps */
83: Nt=Nt+2+_mpfr_ceil_log2(Nt);
84:
85: /* initialise the intermediary variables */
86: mpfr_init(t);
87: mpfr_init(te);
88: mpfr_init(ti);
89:
90: /* Hypot */
91: do {
92: not_exact=0;
93: /* reactualisation of the precision */
94: mpfr_set_prec(t,Nt);
95: mpfr_set_prec(te,Nt);
96: mpfr_set_prec(ti,Nt);
97:
98: /* computations of hypot */
99: if(mpfr_mul(te,x,x,GMP_RNDN)) /* x^2 */
100: not_exact=1;
101:
102: if(mpfr_mul(ti,y,y,GMP_RNDN)) /* y^2 */
103: not_exact=1;
104:
105: if(mpfr_add(t,te,ti,GMP_RNDD)) /*x^2+y^2*/
106: not_exact=1;
107:
108: if(mpfr_sqrt(t,t,GMP_RNDN)) /* sqrt(x^2+y^2)*/
109: not_exact=1;
110:
111: /* estimation of the error */
112: err=Nt-(2);
113:
114: Nt += 10;
115: if(Nt<0)Nt=0;
116:
117: } while ((err <0) || ((!mpfr_can_round(t,err,GMP_RNDN,rnd_mode,Nz)) && not_exact));
118:
119: inexact = mpfr_set (z, t, rnd_mode);
120: mpfr_clear(t);
121: mpfr_clear(ti);
122: mpfr_clear(te);
123:
124: }
125:
126: if (not_exact == 0 && inexact == 0)
127: return 0;
128:
129: if (not_exact != 0 && inexact == 0)
130: return 1;
131:
132: return inexact;
133: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>