PR libfortran/18966
[official-gcc.git] / libgfortran / intrinsics / c99_functions.c
blobe3e0d6c8517921281001a0004f16807e375d089d
1 /* Implementation of various C99 functions
2 Copyright (C) 2004 Free Software Foundation, Inc.
4 This file is part of the GNU Fortran 95 runtime library (libgfortran).
6 Libgfortran is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 Libgfortran is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with libgfortran; see the file COPYING.LIB. If not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 #include "config.h"
22 #include <sys/types.h>
23 #include <float.h>
24 #include <math.h>
25 #include "libgfortran.h"
28 #ifndef HAVE_ACOSF
29 float
30 acosf(float x)
32 return (float) acos(x);
34 #endif
36 #ifndef HAVE_ASINF
37 float
38 asinf(float x)
40 return (float) asin(x);
42 #endif
44 #ifndef HAVE_ATAN2F
45 float
46 atan2f(float y, float x)
48 return (float) atan2(y, x);
50 #endif
52 #ifndef HAVE_ATANF
53 float
54 atanf(float x)
56 return (float) atan(x);
58 #endif
60 #ifndef HAVE_CEILF
61 float
62 ceilf(float x)
64 return (float) ceil(x);
66 #endif
68 #ifndef HAVE_COPYSIGNF
69 float
70 copysignf(float x, float y)
72 return (float) copysign(x, y);
74 #endif
76 #ifndef HAVE_COSF
77 float
78 cosf(float x)
80 return (float) cos(x);
82 #endif
84 #ifndef HAVE_COSHF
85 float
86 coshf(float x)
88 return (float) cosh(x);
90 #endif
92 #ifndef HAVE_EXPF
93 float
94 expf(float x)
96 return (float) exp(x);
98 #endif
100 #ifndef HAVE_FABSF
101 float
102 fabsf(float x)
104 return (float) fabs(x);
106 #endif
108 #ifndef HAVE_FLOORF
109 float
110 floorf(float x)
112 return (float) floor(x);
114 #endif
116 #ifndef HAVE_FREXPF
117 float
118 frexpf(float x, int *exp)
120 return (float) frexp(x, exp);
122 #endif
124 #ifndef HAVE_HYPOTF
125 float
126 hypotf(float x, float y)
128 return (float) hypot(x, y);
130 #endif
132 #ifndef HAVE_LOGF
133 float
134 logf(float x)
136 return (float) log(x);
138 #endif
140 #ifndef HAVE_LOG10F
141 float
142 log10f(float x)
144 return (float) log10(x);
146 #endif
148 #ifndef HAVE_SCALBNF
149 float
150 scalbnf(float x, int y)
152 return (float) scalbn(x, y);
154 #endif
156 #ifndef HAVE_SINF
157 float
158 sinf(float x)
160 return (float) sin(x);
162 #endif
164 #ifndef HAVE_SINHF
165 float
166 sinhf(float x)
168 return (float) sinh(x);
170 #endif
172 #ifndef HAVE_SQRTF
173 float
174 sqrtf(float x)
176 return (float) sqrt(x);
178 #endif
180 #ifndef HAVE_TANF
181 float
182 tanf(float x)
184 return (float) tan(x);
186 #endif
188 #ifndef HAVE_TANHF
189 float
190 tanhf(float x)
192 return (float) tanh(x);
194 #endif
196 #ifndef HAVE_NEXTAFTERF
197 /* This is a portable implementation of nextafterf that is intended to be
198 independent of the floating point format or its in memory representation.
199 This implementation works correctly with denormalized values. */
200 float
201 nextafterf(float x, float y)
203 /* This variable is marked volatile to avoid excess precision problems
204 on some platforms, including IA-32. */
205 volatile float delta;
206 float absx, denorm_min;
208 if (isnan(x) || isnan(y))
209 return x + y;
210 if (x == y)
211 return x;
213 /* absx = fabsf (x); */
214 absx = (x < 0.0) ? -x : x;
216 /* __FLT_DENORM_MIN__ is non-zero iff the target supports denormals. */
217 if (__FLT_DENORM_MIN__ == 0.0f)
218 denorm_min = __FLT_MIN__;
219 else
220 denorm_min = __FLT_DENORM_MIN__;
222 if (absx < __FLT_MIN__)
223 delta = denorm_min;
224 else
226 float frac;
227 int exp;
229 /* Discard the fraction from x. */
230 frac = frexpf (absx, &exp);
231 delta = scalbnf (0.5f, exp);
233 /* Scale x by the epsilon of the representation. By rights we should
234 have been able to combine this with scalbnf, but some targets don't
235 get that correct with denormals. */
236 delta *= __FLT_EPSILON__;
238 /* If we're going to be reducing the absolute value of X, and doing so
239 would reduce the exponent of X, then the delta to be applied is
240 one exponent smaller. */
241 if (frac == 0.5f && (y < x) == (x > 0))
242 delta *= 0.5f;
244 /* If that underflows to zero, then we're back to the minimum. */
245 if (delta == 0.0f)
246 delta = denorm_min;
249 if (y < x)
250 delta = -delta;
252 return x + delta;
254 #endif
257 #ifndef HAVE_POWF
258 float
259 powf(float x, float y)
261 return (float) pow(x, y);
263 #endif
265 /* Note that if fpclassify is not defined, then NaN is not handled */
267 /* Algorithm by Steven G. Kargl. */
269 #ifndef HAVE_ROUND
270 /* Round to nearest integral value. If the argument is halfway between two
271 integral values then round away from zero. */
273 double
274 round(double x)
276 double t;
277 #if defined(fpclassify)
278 int i;
279 i = fpclassify(x);
280 if (i == FP_INFINITE || i == FP_NAN)
281 return (x);
282 #endif
284 if (x >= 0.0)
286 t = ceil(x);
287 if (t - x > 0.5)
288 t -= 1.0;
289 return (t);
291 else
293 t = ceil(-x);
294 if (t + x > 0.5)
295 t -= 1.0;
296 return (-t);
299 #endif
301 #ifndef HAVE_ROUNDF
302 /* Round to nearest integral value. If the argument is halfway between two
303 integral values then round away from zero. */
305 float
306 roundf(float x)
308 float t;
309 #if defined(fpclassify)
310 int i;
312 i = fpclassify(x);
313 if (i == FP_INFINITE || i == FP_NAN)
314 return (x);
315 #endif
317 if (x >= 0.0)
319 t = ceilf(x);
320 if (t - x > 0.5)
321 t -= 1.0;
322 return (t);
324 else
326 t = ceilf(-x);
327 if (t + x > 0.5)
328 t -= 1.0;
329 return (-t);
332 #endif