verify: new macro 'assume'
[gnulib.git] / lib / copysignl.c
1 /* Copy sign into another 'long double' number.
2    Copyright (C) 2011-2013 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3 of the License, or
7    (at your option) any later version.
8
9    This program 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 General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
16
17 #include <config.h>
18
19 /* Specification.  */
20 #include <math.h>
21
22 #if HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
23
24 long double
25 copysignl (long double x, long double y)
26 {
27   return copysign (x, y);
28 }
29
30 #else
31
32 # if defined __hpux && !defined __GNUC__
33
34 #  include <float.h>
35
36 /* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0L.  */
37 static long double
38 compute_minus_zerol (void)
39 {
40   return -LDBL_MIN * LDBL_MIN;
41 }
42 #  define minus_zerol compute_minus_zerol ()
43
44 /* HP cc on HP-UX 11 has a bug: When x is a positive zero, - x comes out
45    as a positive zero, rather than as a minus zero.  Work around it.  */
46 static long double
47 unary_minus (long double x)
48 {
49   if (x == 0.0L)
50     {
51       if (signbit (x))
52         return 0.0L;
53       else
54         return minus_zerol;
55     }
56   else
57     return - x;
58 }
59
60 # endif
61
62 long double
63 copysignl (long double x, long double y)
64 {
65 # if defined __hpux && !defined __GNUC__
66   return (signbit (x) != signbit (y) ? unary_minus (x) : x);
67 # else
68   return (signbit (x) != signbit (y) ? - x : x);
69 # endif
70 }
71
72 #endif