1
0

sincosl.c 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #define _GNU_SOURCE
  2. #include "libm.h"
  3. #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
  4. void sincosl(long double x, long double *sin, long double *cos)
  5. {
  6. double sind, cosd;
  7. sincos(x, &sind, &cosd);
  8. *sin = sind;
  9. *cos = cosd;
  10. }
  11. #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
  12. void sincosl(long double x, long double *sin, long double *cos)
  13. {
  14. union ldshape u = {x};
  15. unsigned n;
  16. long double y[2], s, c;
  17. u.i.se &= 0x7fff;
  18. if (u.i.se == 0x7fff) {
  19. *sin = *cos = x - x;
  20. return;
  21. }
  22. if (u.f < M_PI_4) {
  23. if (u.i.se < 0x3fff - LDBL_MANT_DIG) {
  24. /* raise underflow if subnormal */
  25. if (u.i.se == 0) FORCE_EVAL(x*0x1p-120f);
  26. *sin = x;
  27. /* raise inexact if x!=0 */
  28. *cos = 1.0 + x;
  29. return;
  30. }
  31. *sin = __sinl(x, 0, 0);
  32. *cos = __cosl(x, 0);
  33. return;
  34. }
  35. n = __rem_pio2l(x, y);
  36. s = __sinl(y[0], y[1], 1);
  37. c = __cosl(y[0], y[1]);
  38. switch (n & 3) {
  39. case 0:
  40. *sin = s;
  41. *cos = c;
  42. break;
  43. case 1:
  44. *sin = c;
  45. *cos = -s;
  46. break;
  47. case 2:
  48. *sin = -s;
  49. *cos = -c;
  50. break;
  51. case 3:
  52. default:
  53. *sin = -c;
  54. *cos = s;
  55. break;
  56. }
  57. }
  58. #endif