exp2l: Work around a NetBSD 10.0/i386 bug.
[gnulib.git] / lib / hypotl.c
blobf84b941871e1f8e25a5b7a6cf52a34d326effcc1
1 /* Hypotenuse of a right-angled triangle.
2 Copyright (C) 2012-2024 Free Software Foundation, Inc.
4 This file is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation, either version 3 of the
7 License, or (at your option) any later version.
9 This file is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 /* Written by Bruno Haible <bruno@clisp.org>, 2012. */
19 #include <config.h>
21 /* Specification. */
22 #include <math.h>
24 #if HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
26 long double
27 hypotl (long double x, long double y)
29 return hypot (x, y);
32 #else
34 long double
35 hypotl (long double x, long double y)
37 if (isfinite (x) && isfinite (y))
39 /* Determine absolute values. */
40 x = fabsl (x);
41 y = fabsl (y);
44 /* Find the bigger and the smaller one. */
45 long double a;
46 long double b;
48 if (x >= y)
50 a = x;
51 b = y;
53 else
55 a = y;
56 b = x;
58 /* Now 0 <= b <= a. */
61 int e;
62 long double an;
63 long double bn;
65 /* Write a = an * 2^e, b = bn * 2^e with 0 <= bn <= an < 1. */
66 an = frexpl (a, &e);
67 bn = ldexpl (b, - e);
70 long double cn;
72 /* Through the normalization, no unneeded overflow or underflow
73 will occur here. */
74 cn = sqrtl (an * an + bn * bn);
75 return ldexpl (cn, e);
80 else
82 if (isinf (x) || isinf (y))
83 /* x or y is infinite. Return +Infinity. */
84 return HUGE_VALL;
85 else
86 /* x or y is NaN. Return NaN. */
87 return x + y;
91 #endif