diff options
author | daney <daney@280ebfd0-de03-0410-8827-d642c229c3f4> | 2001-10-26 15:31:42 +0000 |
---|---|---|
committer | daney <daney@280ebfd0-de03-0410-8827-d642c229c3f4> | 2001-10-26 15:31:42 +0000 |
commit | 352cf452bda69e3edbb9b0dfeb6c9767e9095b0c (patch) | |
tree | f4b59a41c956d4d52ddfd5aeb54f8b2bc39d42dc /hypot.c | |
parent | 8644a231c5ece134c213e58224c26b1b6d80775f (diff) | |
download | mpfr-352cf452bda69e3edbb9b0dfeb6c9767e9095b0c.tar.gz |
add some flags
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@1433 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'hypot.c')
-rw-r--r-- | hypot.c | 158 |
1 files changed, 82 insertions, 76 deletions
@@ -43,94 +43,100 @@ mpfr_hypot (z, x,y, rnd_mode) #endif { int inexact; + /* Flag calcul exacte */ + int not_exact=0; - /* particular cases */ + /* particular cases */ - if (MPFR_IS_NAN(x) || MPFR_IS_NAN(y)) - { - MPFR_SET_NAN(z); - return 1; - } + if (MPFR_IS_NAN(x) || MPFR_IS_NAN(y)) + { + MPFR_SET_NAN(z); + return 1; + } - MPFR_CLEAR_NAN(z); + MPFR_CLEAR_NAN(z); - if (MPFR_IS_INF(x) || MPFR_IS_INF(y)) - { - MPFR_SET_INF(z); - if (MPFR_SIGN(z) < 0) - MPFR_CHANGE_SIGN(z); - return 0; - } + if (MPFR_IS_INF(x) || MPFR_IS_INF(y)) + { + MPFR_SET_INF(z); + if (MPFR_SIGN(z) < 0) + MPFR_CHANGE_SIGN(z); + return 0; + } - MPFR_CLEAR_INF(z); + MPFR_CLEAR_INF(z); - if(!MPFR_NOTZERO(x)) - return mpfr_abs (z, y, rnd_mode); - - if(!MPFR_NOTZERO(y)) - return mpfr_abs (z, x, rnd_mode); - - /* General case */ - - { - /* Declaration of the intermediary variable */ - mpfr_t t, te,ti; - - /* Flag calcul exacte */ - int not_exact=0; - - /* Declaration of the size variable */ - mp_prec_t Nx = MPFR_PREC(x); /* Precision of input variable */ - mp_prec_t Ny = MPFR_PREC(y); /* Precision of input variable */ - mp_prec_t Nz = MPFR_PREC(z); /* Precision of input variable */ + if(!MPFR_NOTZERO(x)) + return mpfr_abs (z, y, rnd_mode); + + if(!MPFR_NOTZERO(y)) + return mpfr_abs (z, x, rnd_mode); + + /* General case */ + + { + /* Declaration of the intermediary variable */ + mpfr_t t, te,ti; + /* Declaration of the size variable */ + mp_prec_t Nx = MPFR_PREC(x); /* Precision of input variable */ + mp_prec_t Ny = MPFR_PREC(y); /* Precision of input variable */ + mp_prec_t Nz = MPFR_PREC(z); /* Precision of input variable */ - mp_prec_t Nt; /* Precision of the intermediary variable */ - long int err; /* Precision of error */ + int Nt; /* Precision of the intermediary variable */ + long int err; /* Precision of error */ - /* compute the precision of intermediary variable */ - Nt=MAX(MAX(Nx,Ny),Nz); - - /* compute the size of intermediary variable -- see algorithms.ps */ - Nt=Nt+2+_mpfr_ceil_log2(Nt); - - /* initialise the intermediary variables */ - mpfr_init(t); - mpfr_init(te); - mpfr_init(ti); - - /* Hypot */ - do { - not_exact=0; - /* reactualisation of the precision */ - mpfr_set_prec(t,Nt); - mpfr_set_prec(te,Nt); - mpfr_set_prec(ti,Nt); - - /* computations of hypot */ - if(mpfr_mul(te,x,x,GMP_RNDN)) /* x^2 */ - not_exact=1; - - if(mpfr_mul(ti,y,y,GMP_RNDN)) /* y^2 */ - not_exact=1; - - if(mpfr_add(t,te,ti,GMP_RNDD)) /*x^2+y^2*/ - not_exact=1; + /* compute the precision of intermediary variable */ + Nt=MAX(MAX(Nx,Ny),Nz); + + /* compute the size of intermediary variable -- see algorithms.ps */ + Nt=Nt+2+_mpfr_ceil_log2(Nt); + + /* initialise the intermediary variables */ + mpfr_init(t); + mpfr_init(te); + mpfr_init(ti); + + /* Hypot */ + do { + not_exact=0; + /* reactualisation of the precision */ + mpfr_set_prec(t,Nt); + mpfr_set_prec(te,Nt); + mpfr_set_prec(ti,Nt); + + /* computations of hypot */ + if(mpfr_mul(te,x,x,GMP_RNDN)) /* x^2 */ + not_exact=1; + + if(mpfr_mul(ti,y,y,GMP_RNDN)) /* y^2 */ + not_exact=1; + + if(mpfr_add(t,te,ti,GMP_RNDD)) /*x^2+y^2*/ + not_exact=1; - if(mpfr_sqrt(t,t,GMP_RNDN)) /* sqrt(x^2+y^2)*/ - not_exact=1; + if(mpfr_sqrt(t,t,GMP_RNDN)) /* sqrt(x^2+y^2)*/ + not_exact=1; - /* estimation of the error */ - err=Nt-(2); + /* estimation of the error */ + err=Nt-(2); - Nt += 10; + Nt += 10; + if(Nt<0)Nt=0; + + } while ((err <0) || ((!mpfr_can_round(t,err,GMP_RNDN,rnd_mode,Nz)) && not_exact)); + + inexact = mpfr_set (z, t, rnd_mode); + mpfr_clear(t); + mpfr_clear(ti); + mpfr_clear(te); - } while ((err <0) || ((!mpfr_can_round(t,err,GMP_RNDN,rnd_mode,Nz)) && not_exact)); + } - inexact = mpfr_set (z, t, rnd_mode); - mpfr_clear(t); - mpfr_clear(ti); - mpfr_clear(te); + if (not_exact == 0 && inexact == 0) + return 0; + + if (not_exact != 0 && inexact == 0) + return 1; - } - return inexact; + return inexact; } |