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