1
0

sincosl.c 991 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  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. sincos(x, (double *)sin, (double *)cos);
  7. }
  8. #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
  9. void sincosl(long double x, long double *sin, long double *cos)
  10. {
  11. union IEEEl2bits u;
  12. int n;
  13. long double y[2], s, c;
  14. u.e = x;
  15. u.bits.sign = 0;
  16. /* x = +-0 or subnormal */
  17. if (!u.bits.exp) {
  18. *sin = x;
  19. *cos = 1.0;
  20. return;
  21. }
  22. /* x = nan or inf */
  23. if (u.bits.exp == 0x7fff) {
  24. *sin = *cos = x - x;
  25. return;
  26. }
  27. /* |x| < pi/4 */
  28. if (u.e < M_PI_4) {
  29. *sin = __sinl(x, 0, 0);
  30. *cos = __cosl(x, 0);
  31. return;
  32. }
  33. n = __rem_pio2l(x, y);
  34. s = __sinl(y[0], y[1], 1);
  35. c = __cosl(y[0], y[1]);
  36. switch (n & 3) {
  37. case 0:
  38. *sin = s;
  39. *cos = c;
  40. break;
  41. case 1:
  42. *sin = c;
  43. *cos = -s;
  44. break;
  45. case 2:
  46. *sin = -s;
  47. *cos = -c;
  48. break;
  49. case 3:
  50. default:
  51. *sin = -c;
  52. *cos = s;
  53. break;
  54. }
  55. }
  56. #endif