2 Copyright (C) 2012-2020 Free Software Foundation, Inc.
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.
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.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 #if ! (defined USE_LONG_DOUBLE || defined USE_FLOAT)
24 #ifdef USE_LONG_DOUBLE
25 # define REMAINDER remainderl
26 # define DOUBLE long double
27 # define L_(literal) literal##L
31 #elif ! defined USE_FLOAT
32 # define REMAINDER remainder
33 # define DOUBLE double
34 # define L_(literal) literal
38 #else /* defined USE_FLOAT */
39 # define REMAINDER remainderf
41 # define L_(literal) literal##f
50 # define NAN (zero / zero)
52 # define NAN (L_(0.0) / L_(0.0))
56 REMAINDER (DOUBLE x
, DOUBLE y
)
58 if (isfinite (x
) && isfinite (y
) && y
!= L_(0.0))
61 /* Return x, regardless of the sign of y. */
65 int negate
= ((!signbit (x
)) ^ (!signbit (y
)));
68 /* Take the absolute value of x and y. */
72 /* Trivial case that requires no computation. */
74 return (negate
? - x
: x
);
76 /* With a fixed y, the function x -> remainder(x,y) has a period 2*y.
77 Therefore we can reduce the argument x modulo 2*y. And it's no
78 problem if 2*y overflows, since fmod(x,Inf) = x. */
79 x
= FMOD (x
, L_(2.0) * y
);
81 /* Consider the 3 cases:
84 1.5 * y <= x <= 2.0 * y */
93 return (negate
? - r
: r
);
98 if (ISNAN (x
) || ISNAN (y
))
99 return x
+ y
; /* NaN */
103 /* x infinite or y zero */