beta-0.89.2
[luatex.git] / source / libs / mpfr / mpfr-3.1.3 / src / reldiff.c
blob058e39da60404424132337ed48edc7be842017d4
1 /* mpfr_reldiff -- compute relative difference of two floating-point numbers.
3 Copyright 2000-2001, 2004-2015 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramel projects, INRIA.
6 This file is part of the GNU MPFR Library.
8 The GNU MPFR Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
13 The GNU MPFR Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
20 http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
23 #include "mpfr-impl.h"
25 /* reldiff(b, c) = abs(b-c)/b */
26 void
27 mpfr_reldiff (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
29 mpfr_t b_copy;
31 if (MPFR_ARE_SINGULAR (b, c))
33 if (MPFR_IS_NAN(b) || MPFR_IS_NAN(c))
35 MPFR_SET_NAN(a);
36 return;
38 else if (MPFR_IS_INF(b))
40 if (MPFR_IS_INF (c) && (MPFR_SIGN (c) == MPFR_SIGN (b)))
41 MPFR_SET_ZERO(a);
42 else
43 MPFR_SET_NAN(a);
44 return;
46 else if (MPFR_IS_INF(c))
48 MPFR_SET_SAME_SIGN (a, b);
49 MPFR_SET_INF (a);
50 return;
52 else if (MPFR_IS_ZERO(b)) /* reldiff = abs(c)/c = sign(c) */
54 mpfr_set_si (a, MPFR_INT_SIGN (c), rnd_mode);
55 return;
57 /* Fall through */
60 if (a == b)
62 mpfr_init2 (b_copy, MPFR_PREC(b));
63 mpfr_set (b_copy, b, MPFR_RNDN);
66 mpfr_sub (a, b, c, rnd_mode);
67 mpfr_abs (a, a, rnd_mode); /* for compatibility with MPF */
68 mpfr_div (a, a, (a == b) ? b_copy : b, rnd_mode);
70 if (a == b)
71 mpfr_clear (b_copy);