1 /*
2  * Copyright (c) 1994 Cygnus Support.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * and/or other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * at Cygnus Support, Inc.  Cygnus Support, Inc. may not be used to
11  * endorse or promote products derived from this software without
12  * specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 /*
18   Test the library maths functions using trusted precomputed test
19   vectors.
20 
21   These vectors were originally generated on a sun3 with a 68881 using
22   80 bit precision, but ...
23 
24   Each function is called with a variety of interesting arguments.
25   Note that many of the polynomials we use behave badly when the
26   domain is stressed, so the numbers in the vectors depend on what is
27   useful to test - eg sin(1e30) is pointless - the arg has to be
28   reduced modulo pi, and after that there's no bits of significance
29   left to evaluate with - any number would be just as precise as any
30   other.
31 
32 
33 */
34 
35 #include "test.h"
36 #include <math.h>
37 #include <float.h>
38 #include <errno.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <stdbool.h>
42 
43 #ifndef _IEEE_754_2008_SNAN
44 # define _IEEE_754_2008_SNAN 1
45 #endif
46 
47 extern int inacc;
48 
49 int merror;
50 double mretval = 64;
51 int traperror = 1;
52 char *mname;
53 
54 #ifdef INCLUDE_GENERATE
55 static void
translate_to(FILE * file,double r)56 translate_to (FILE *file,
57 	    double r)
58 {
59   __ieee_double_shape_type bits;
60   bits.value = r;
61   fprintf(file, "0x%08lx, 0x%08lx", (unsigned long) bits.parts.msw, (unsigned long) bits.parts.lsw);
62 }
63 #endif
64 
65 double
66 thedouble (uint32_t msw,
67            uint32_t lsw, volatile double *r);
68 
69 /* Convert double to float, preserving issignaling status and NaN sign */
70 
71 #define to_float(f,d)	do {					\
72 		if (__issignaling(d)) {				\
73 			if (signbit(d))				\
74 				(f) = -__builtin_nansf("");	\
75 			else					\
76 				(f) =  __builtin_nansf("");	\
77 		} else if (isnan(d)) {				\
78 			if (signbit(d))				\
79 				(f) = -__builtin_nanf("");	\
80 			else					\
81 				(f) =  __builtin_nanf("");	\
82 		} else						\
83 			(f) = (float) (d);			\
84 	} while(0)
85 
86 #define to_double(d,f)	do {					\
87 		if (__issignalingf(f)) {				\
88 			if (signbit(f))				\
89 				(d) = -__builtin_nans("");	\
90 			else					\
91 				(d) =  __builtin_nans("");	\
92 		} else if (isnanf(f)) {				\
93 			if (signbit(f))				\
94 				(d) = -__builtin_nan("");	\
95 			else					\
96 				(d) =  __builtin_nan("");	\
97 		} else						\
98 			(d) = (double) (f);			\
99 	} while(0)
100 
101 static int
ffcheck_id(double is,one_line_type * p,char * name,int serrno,int merror,int id)102 ffcheck_id(double is,
103 	   one_line_type *p,
104 	   char *name,
105 	   int serrno,
106 	   int merror,
107 	   int id)
108 {
109   /* Make sure the answer isn't to far wrong from the correct value */
110   __ieee_double_shape_type correct = {}, isbits;
111   int mag;
112   isbits.value = is;
113 
114   (void) serrno;
115   (void) merror;
116 
117   thedouble(p->qs[id].msw, p->qs[id].lsw, &correct.value);
118 
119   int error_bit = p->error_bit;
120 
121   mag = mag_of_error(correct.value, is);
122 
123   if (error_bit > 63)
124     error_bit = 63;
125 
126   /* All signaling nans are the "same", as are all quiet nans.
127    * On i386, just returning a value converts signaling nans to quiet
128    * nans, let that pass
129    */
130   if (isnan(correct.value) && isnan(is)
131 #if !defined(__i386__) && !defined(__HAVE_68881__)
132       && (issignaling(correct.value) == issignaling(is))
133 #endif
134     )
135   {
136     mag = 64;
137   }
138 
139   if (mag < error_bit)
140   {
141     inacc ++;
142 
143     printf("%s:%d, inaccurate answer: bit %d (%08lx%08lx %08lx%08lx) (%g %g)\n",
144 	   name,  p->line, mag,
145 	   (unsigned long) correct.parts.msw,
146 	   (unsigned long) correct.parts.lsw,
147 	   (unsigned long) isbits.parts.msw,
148 	   (unsigned long) isbits.parts.lsw,
149 	   correct.value, is);
150   }
151 
152 #if 0
153   if (p->qs[id].merror != merror)
154   {
155     /* Beware, matherr doesn't exist anymore.  */
156     printf("testing %s_vec.c:%d, matherr wrong: %d %d\n",
157 	   name, p->line, merror, p->qs[id].merror);
158   }
159 
160   if (p->qs[id].errno_val != errno)
161   {
162     printf("testing %s_vec.c:%d, errno wrong: %d %d\n",
163 	   name, p->line, errno, p->qs[id].errno_val);
164 
165   }
166 #endif
167   return mag;
168 }
169 
170 static int
ffcheck(double is,one_line_type * p,char * name,int serrno,int merror)171 ffcheck(double is,
172 	one_line_type *p,
173 	char *name,
174 	int serrno,
175 	int merror)
176 {
177   return ffcheck_id(is, p, name, serrno, merror, 0);
178 }
179 
180 static int
fffcheck_id(float is,one_line_type * p,char * name,int serrno,int merror,int id)181 fffcheck_id (float is,
182 	     one_line_type *p,
183 	     char *name,
184 	     int serrno,
185 	     int merror,
186 	     int id)
187 {
188   /* Make sure the answer isn't to far wrong from the correct value */
189   __ieee_float_shape_type correct, isbits;
190   __ieee_double_shape_type correct_double;
191   __ieee_double_shape_type is_double;
192   int mag;
193 
194   (void) serrno;
195   (void) merror;
196 
197   isbits.value = is;
198   to_double(is_double.value, is);
199 
200   thedouble(p->qs[id].msw,p->qs[id].lsw, &correct_double.value);
201 
202   to_float(correct.value, correct_double.value);
203 //  printf("%s got 0x%08x want 0x%08x\n", name, isbits.p1, correct.p1);
204 
205   int error_bit = p->error_bit;
206 
207   if (error_bit > 31)
208     error_bit = 31;
209 
210   mag = fmag_of_error(correct.value, is);
211 
212   /* All signaling nans are the "same", as are all quiet nans */
213   if (isnan(correct.value) && isnan(is)
214 #if !defined(__i386__) && !defined(__m68k__)
215       /* i386 calling convention ends up always converting snan into qnan */
216       && (__issignalingf(correct.value) == __issignalingf(is))
217 #endif
218 	  )
219   {
220 	mag = 32;
221   }
222 
223   if (mag < error_bit)
224   {
225     inacc ++;
226 
227     printf("%s:%d, inaccurate answer: bit %d (%08lx is %08lx) (%g is %g) (is double 0x%08lx, 0x%08lx)\n",
228 	   name,  p->line, mag,
229 	   (unsigned long) (uint32_t) correct.p1,
230 	   (unsigned long) (uint32_t) isbits.p1,
231 	   (double) correct.value,
232 	   (double) is,
233 	   (unsigned long) (uint32_t) is_double.parts.msw,
234 	   (unsigned long) (uint32_t) is_double.parts.lsw);
235   }
236 
237 #if 0
238   if (p->qs[id].merror != merror)
239   {
240     /* Beware, matherr doesn't exist anymore.  */
241     printf("testing %s_vec.c:%d, matherr wrong: %d %d\n",
242 	   name, p->line, merror, p->qs[id].merror);
243   }
244 
245   if (p->qs[id].errno_val != errno)
246   {
247     printf("testing %s_vec.c:%d, errno wrong: %d %d\n",
248 	   name, p->line, errno, p->qs[id].errno_val);
249 
250   }
251 #endif
252   return mag;
253 }
254 
255 static int
fffcheck(float is,one_line_type * p,char * name,int serrno,int merror)256 fffcheck (float is,
257 	  one_line_type *p,
258 	  char *name,
259 	  int serrno,
260 	  int merror)
261 {
262   return fffcheck_id(is, p, name, serrno, merror, 0);
263 }
264 
265 static
volatile_memcpy(volatile void * dest,void * src,size_t len)266 volatile_memcpy(volatile void *dest, void *src, size_t len)
267 {
268     volatile uint8_t *d = dest;
269     uint8_t *s = src;
270     while (len--)
271         *d++ = *s++;
272 }
273 
274 double
thedouble(uint32_t msw,uint32_t lsw,volatile double * r)275 thedouble (uint32_t msw,
276   uint32_t lsw, volatile double *r)
277 {
278   __ieee_double_shape_type x;
279 
280   x.parts.msw = msw;
281   x.parts.lsw = lsw;
282 #if !_IEEE_754_2008_SNAN
283   if (isnan(x.value))
284       x.parts.msw ^= 0x000c0000;
285 #endif
286   if (r)
287     volatile_memcpy(r, &x.value, sizeof(double));
288   return x.value;
289 }
290 
291 int calc;
292 extern int reduce;
293 
294 
295 #ifdef INCLUDE_GENERATE
296 static void
frontline(FILE * f,int mag,one_line_type * p,double result,int merror,int my_errno,char * args,char * name)297 frontline (FILE *f,
298        int mag,
299        one_line_type *p,
300        double result,
301        int merror,
302        int my_errno,
303        char *args,
304        char *name)
305 {
306   (void) name;
307   /* float returns can never have more than 32 bits of accuracy */
308   if (*args == 'f' && mag > 32)
309     mag = 32;
310 
311   if (reduce && p->error_bit < mag)
312   {
313     fprintf(f, "{%2d,", p->error_bit);
314   }
315   else
316   {
317     fprintf(f, "{%2d,",mag);
318   }
319 
320 
321   fprintf(f,"%2d,%3d,", merror,my_errno);
322   fprintf(f, "__LINE__, ");
323 
324   if (calc)
325   {
326     translate_to(f, result);
327   }
328   else
329   {
330     translate_to(f, thedouble(p->qs[0].msw, p->qs[0].lsw, NULL));
331   }
332 
333   fprintf(f, ", ");
334 
335   fprintf(f,"0x%08lx, 0x%08lx", (unsigned long) p->qs[1].msw, (unsigned long) p->qs[1].lsw);
336 
337 
338   if (args[2])
339   {
340     fprintf(f, ", ");
341     fprintf(f,"0x%08lx, 0x%08lx", (unsigned long) p->qs[2].msw, (unsigned long) p->qs[2].lsw);
342   }
343 
344   fprintf(f,"},	/* %g=f(%g",result,
345   	  thedouble(p->qs[1].msw, p->qs[1].lsw, NULL));
346 
347   if (args[2])
348   {
349     fprintf(f,", %g", thedouble(p->qs[2].msw,p->qs[2].lsw, NULL));
350   }
351   fprintf(f, ")*/\n");
352 }
353 #endif
354 
355 static void
finish(FILE * f,int vector,double result,one_line_type * p,char * args,char * name)356 finish (FILE *f,
357        int vector,
358        double result,
359        one_line_type *p,
360        char *args,
361        char *name)
362 {
363   int mag;
364 
365   mag = ffcheck(result, p,name,  merror, errno);
366   (void) f;
367   (void) vector;
368   (void) args;
369   (void) mag;
370 #ifdef INCLUDE_GENERATE
371   if (vector)
372   {
373     frontline(f, mag, p, result, merror, errno, args , name);
374   }
375 #endif
376 }
377 
378 static void
finish2(FILE * f,int vector,double result,double result2,one_line_type * p,char * args,char * name)379 finish2 (FILE *f,
380 	 int vector,
381 	 double result,
382 	 double result2,
383 	 one_line_type *p,
384 	 char *args,
385 	 char *name)
386 {
387   int mag, mag2;
388 
389   mag = ffcheck(result, p,name,  merror, errno);
390   mag2 = ffcheck_id(result2, p,name,  merror, errno, 2);
391   if (mag2 < mag)
392     mag = mag2;
393   (void) f;
394   (void) vector;
395   (void) mag;
396   (void) args;
397 #ifdef INCLUDE_GENERATE
398   if (vector)
399   {
400     __ieee_double_shape_type result2_double;
401     result2_double.value = result2;
402     p->qs[2].msw = result2_double.parts.msw;
403     p->qs[2].lsw = result2_double.parts.lsw;
404     frontline(f, mag, p, result, merror, errno, args , name);
405   }
406 #endif
407 }
408 
409 static void
ffinish(FILE * f,int vector,float fresult,one_line_type * p,char * args,char * name)410 ffinish (FILE *f,
411        int vector,
412        float fresult,
413        one_line_type *p,
414        char *args,
415        char *name)
416 {
417   int mag;
418 
419   mag = fffcheck(fresult, p,name,  merror, errno);
420   (void) f;
421   (void) vector;
422   (void) args;
423   (void) mag;
424 #ifdef INCLUDE_GENERATE
425   if (vector)
426   {
427     frontline(f, mag, p, (double) fresult, merror, errno, args , name);
428   }
429 #endif
430 }
431 
432 static void
ffinish2(FILE * f,int vector,float fresult,float fresult2,one_line_type * p,char * args,char * name)433 ffinish2 (FILE *f,
434 	  int vector,
435 	  float fresult,
436 	  float fresult2,
437 	  one_line_type *p,
438 	  char *args,
439 	  char *name)
440 {
441   int mag, mag2;
442 
443   mag = fffcheck(fresult, p,name,  merror, errno);
444   mag2 = fffcheck_id(fresult2, p, name, merror, errno, 2);
445   if (mag2 < mag)
446     mag = mag2;
447   (void) f;
448   (void) vector;
449   (void) args;
450   (void) mag;
451 #ifdef INCLUDE_GENERATE
452   if (vector)
453   {
454     __ieee_double_shape_type result2_double;
455     to_double(result2_double.value, (double) fresult2);
456     p->qs[2].msw = result2_double.parts.msw;
457     p->qs[2].lsw = result2_double.parts.lsw;
458     frontline(f, mag, p, (double) fresult, merror, errno, args , name);
459   }
460 #endif
461 }
462 
463 extern int redo;
464 
465 static bool
in_float_range(double arg)466 in_float_range(double arg)
467 {
468 	if (isinf(arg) || isnan(arg))
469 		return true;
470 	return -(double) FLT_MAX <= arg && arg <= (double) FLT_MAX;
471 }
472 
473 void
run_vector_1(int vector,one_line_type * p,char * func,char * name,char * args)474 run_vector_1 (int vector,
475        one_line_type *p,
476        char *func,
477        char *name,
478        char *args)
479 {
480   FILE *f = NULL;
481   double result;
482   float fresult;
483 
484 #ifdef INCLUDE_GENERATE
485   if (vector)
486   {
487 
488     VECOPEN(name, f);
489 
490     if (redo)
491     {
492       double k;
493       union {
494 	struct { uint32_t a, b; };
495 	double d;
496       } d, d4;
497 
498       for (k = -.2; k < .2; k+= 0.00132)
499       {
500 	d.d = k;
501 	d4.d = k + 4;
502 	fprintf(f,"{1,1, 1,1, 0,0,0x%08lx,0x%08lx, 0x%08lx, 0x%08lx},\n",
503 		(unsigned long) d.a, (unsigned long) d.b, (unsigned long) d4.a, (unsigned long) d4.b);
504 
505       }
506 
507       for (k = -1.2; k < 1.2; k+= 0.01)
508       {
509 	d.d = k;
510 	d4.d = k + 4;
511 	fprintf(f,"{1,1, 1,1, 0,0,0x%08lx,0x%08lx, 0x%08lx, 0x%08lx},\n",
512 		(unsigned long) d.a, (unsigned long) d.b, (unsigned long) d4.a, (unsigned long) d4.b);
513 
514       }
515       for (k = -M_PI *2; k < M_PI *2; k+= M_PI/2)
516       {
517 	d.d = k;
518 	d4.d = k + 4;
519 	fprintf(f,"{1,1, 1,1, 0,0,0x%08lx,0x%08lx, 0x%08lx, 0x%08lx},\n",
520 		(unsigned long) d.a, (unsigned long) d.b, (unsigned long) d4.a, (unsigned long) d4.b);
521 
522       }
523 
524       for (k = -30; k < 30; k+= 1.7)
525       {
526 	d.d = k;
527 	d4.d = k + 4;
528 	fprintf(f,"{2,2, 1,1, 0,0, 0x%08lx,0x%08lx, 0x%08lx, 0x%08lx},\n",
529 		(unsigned long) d.a, (unsigned long) d.b, (unsigned long) d4.a, (unsigned long) d4.b);
530 
531       }
532       VECCLOSE(f, name, args);
533       return;
534     }
535   }
536 #endif
537 
538   newfunc(name);
539   while (p->line)
540   {
541     volatile double arg1;
542     thedouble(p->qs[1].msw, p->qs[1].lsw, &arg1);
543     volatile double arg2;
544     thedouble(p->qs[2].msw, p->qs[2].lsw, &arg2);
545 
546     errno = 0;
547     merror = 0;
548     mname = 0;
549 
550 
551     line(p->line);
552 
553     merror = 0;
554     errno = 123;
555 
556     if (strcmp(args,"dd")==0)
557     {
558       typedef double (*pdblfunc) (double);
559 
560       /* Double function returning a double */
561 
562       result = ((pdblfunc)(func))(arg1);
563 
564       finish(f,vector, result, p, args, name);
565     }
566     else  if (strcmp(args,"ff")==0)
567     {
568       float arga;
569 
570       typedef float (*pdblfunc) (float);
571 
572       /* Double function returning a double */
573 
574       if (in_float_range(arg1))
575       {
576 	to_float(arga, arg1);
577 	fresult = ((pdblfunc)(func))(arga);
578 	ffinish(f, vector, fresult, p,args, name);
579       }
580     }
581     else if (strcmp(args,"ddd")==0)
582      {
583        typedef double (*pdblfunc) (double,double);
584 
585        result = ((pdblfunc)(func))(arg1,arg2);
586        finish(f, vector, result, p,args, name);
587      }
588      else  if (strcmp(args,"fff")==0)
589      {
590        volatile float arga;
591        volatile float argb;
592 
593        typedef float (*pdblfunc) (float,float);
594 
595        if (in_float_range(arg1) && in_float_range(arg2))
596        {
597 	 to_float(arga, arg1);
598 	 to_float(argb, arg2);
599 	 fresult = ((pdblfunc)(func))(arga, argb);
600 //	 printf("0x%08x = %s(0x%08x, 0x%08x)\n",
601 //		float_bits(fresult), name, float_bits(arga), float_bits(argb));
602 	 ffinish(f, vector, fresult, p,args, name);
603        }
604      }
605      else if (strcmp(args,"did")==0)
606      {
607        typedef double (*pdblfunc) (int,double);
608 
609        result = ((pdblfunc)(func))((int)arg1,arg2);
610        finish(f, vector, result, p,args, name);
611      }
612      else  if (strcmp(args,"fif")==0)
613      {
614        float argb;
615 
616        typedef float (*pdblfunc) (int,float);
617 
618 
619        if (in_float_range(arg2))
620        {
621 	 to_float(argb, arg2);
622 	 fresult = ((pdblfunc)(func))((int)arg1, argb);
623 	 ffinish(f, vector, fresult, p,args, name);
624        }
625      }
626      else if (strcmp(args,"id")==0)
627      {
628        typedef int (*pdblfunc)(double);
629 
630        result = (double) ((pdblfunc)(func))(arg1);
631        finish(f, vector, result, p, args, name);
632      }
633      else if (strcmp(args,"ddp") == 0)
634      {
635        typedef double (*pdblfunc)(double, double *);
636        double result2;
637 
638        result = (double) ((pdblfunc)(func))(arg1, &result2);
639        finish2(f, vector, result, result2, p, args, name);
640      }
641      else if (strcmp(args,"ffp") == 0)
642      {
643        typedef float (*pdblfunc)(float, float *);
644        float result2;
645 
646        fresult = (float) ((pdblfunc)(func))(arg1, &result2);
647        ffinish2(f, vector, fresult, result2, p, args, name);
648      }
649      else if (strcmp(args,"ddi") == 0)
650      {
651        typedef double (*pdblfunc)(double, int);
652 
653        result = ((pdblfunc)func) (arg1, (int) arg2);
654        finish(f, vector, result, p, args, name);
655      }
656      else if (strcmp(args,"ffi") == 0)
657      {
658        typedef float (*pdblfunc)(float, int);
659 
660        fresult = ((pdblfunc)func) (arg1, (int) arg2);
661        ffinish(f, vector, fresult, p, args, name);
662      }
663     p++;
664   }
665   if (vector && f)
666   {
667     VECCLOSE(f, name, args);
668   }
669 }
670 
671 void
test_math(int vector)672 test_math (int vector)
673 {
674   (void) vector;
675 #if TEST_PART == 0 || TEST_PART == -1
676   test_acos(vector);
677   test_acosf(vector);
678   test_acosh(vector);
679   test_acoshf(vector);
680   test_asin(vector);
681   test_asinf(vector);
682   test_asinh(vector);
683   test_asinhf(vector);
684   test_atan(vector);
685 #endif
686 #if TEST_PART > 0 || TEST_PART == -1
687   test_atan2(vector);
688   test_atan2f(vector);
689 #endif
690 #if TEST_PART == 0 || TEST_PART == -1
691   test_atanf(vector);
692   test_atanh(vector);
693   test_atanhf(vector);
694   test_ceil(vector);
695   test_ceilf(vector);
696   test_copysign(vector);
697   test_copysignf(vector);
698   test_cos(vector);
699   test_cosf(vector);
700   test_cosh(vector);
701   test_coshf(vector);
702   test_erf(vector);
703   test_erfc(vector);
704   test_erfcf(vector);
705   test_erff(vector);
706   test_exp(vector);
707   test_expf(vector);
708 #endif
709 #if TEST_PART == 1 || TEST_PART == -1
710   test_fabs(vector);
711   test_fabsf(vector);
712   test_floor(vector);
713   test_floorf(vector);
714   test_fmod(vector);
715   test_fmodf(vector);
716   test_gamma(vector);
717   test_gammaf(vector);
718   test_hypot(vector);
719   test_hypotf(vector);
720   test_issignaling(vector);
721   test_j0(vector);
722   test_j0f(vector);
723   test_j1(vector);
724   test_j1f(vector);
725   test_jn(vector);
726   test_jnf(vector);
727   test_log(vector);
728   test_log10(vector);
729   test_log10f(vector);
730   test_log1p(vector);
731   test_log1pf(vector);
732   test_log2(vector);
733   test_log2f(vector);
734   test_logf(vector);
735 #endif
736 #if TEST_PART == 2 || TEST_PART == -1
737   test_modf(vector);
738   test_modff(vector);
739   test_pow_vec(vector);
740   test_powf_vec(vector);
741   test_scalb(vector);
742   test_scalbf(vector);
743   test_scalbn(vector);
744   test_scalbnf(vector);
745   test_sin(vector);
746   test_sinf(vector);
747   test_sinh(vector);
748   test_sinhf(vector);
749   test_sqrt(vector);
750   test_sqrtf(vector);
751   test_tan(vector);
752   test_tanf(vector);
753   test_tanh(vector);
754   test_tanhf(vector);
755   test_trunc(vector);
756   test_truncf(vector);
757   test_y0(vector);
758   test_y0f(vector);
759   test_y1(vector);
760   test_y1f(vector);
761   test_y1f(vector);
762   test_ynf(vector);
763 #endif
764 }
765 
766 /* These have to be played with to get to compile on machines which
767    don't have the fancy <foo>f entry points
768 */
769 
770 #if 0
771 float cosf (float a) { return cos((double)a); }
772 float sinf (float  a) { return sin((double)a); }
773 float log1pf (float a) { return log1p((double)a); }
774 float tanf (float a) { return tan((double)a); }
775 float ceilf (float a) { return ceil(a); }
776 float floorf (float a) { return floor(a); }
777 #endif
778 
779 /*ndef HAVE_FLOAT*/
780 #if 0
781 
782 float fmodf(a,b) float a,b; { return fmod(a,b); }
783 float hypotf(a,b) float a,b; { return hypot(a,b); }
784 
785 float acosf(a) float a; { return acos(a); }
786 float acoshf(a) float a; { return acosh(a); }
787 float asinf(a) float a; { return asin(a); }
788 float asinhf(a) float a; { return asinh(a); }
789 float atanf(a) float a; { return atan(a); }
790 float atanhf(a) float a; { return atanh(a); }
791 
792 float coshf(a) float a; { return cosh(a); }
793 float erff(a) float a; { return erf(a); }
794 float erfcf(a) float a; { return erfc(a); }
795 float expf(a) float a; { return exp(a); }
796 float fabsf(a) float a; { return fabs(a); }
797 
798 float gammaf(a) float a; { return gamma(a); }
799 float j0f(a) float a; { return j0(a); }
800 float j1f(a) float a; { return j1(a); }
801 float log10f(a) float a; { return log10(a); }
802 
803 float logf(a) float a; { return log(a); }
804 
805 float sinhf(a) float a; { return sinh(a); }
806 float sqrtf(a) float a; { return sqrt(a); }
807 
808 float tanhf(a) float a; { return tanh(a); }
809 float y0f(a) float a; { return y0(a); }
810 float y1f(a) float a; { return y1(a); }
811 #endif
812