sincosl.c 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  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. unsigned n;
  13. long double y[2], s, c;
  14. u.e = x;
  15. u.bits.sign = 0;
  16. /* x = nan or inf */
  17. if (u.bits.exp == 0x7fff) {
  18. *sin = *cos = x - x;
  19. return;
  20. }
  21. /* |x| < (double)pi/4 */
  22. if (u.e < M_PI_4) {
  23. /* |x| < 0x1p-64 */
  24. if (u.bits.exp < 0x3fff - 64) {
  25. /* raise underflow if subnormal */
  26. if (u.bits.exp == 0) FORCE_EVAL(x*0x1p-120f);
  27. *sin = x;
  28. /* raise inexact if x!=0 */
  29. *cos = 1.0 + x;
  30. return;
  31. }
  32. *sin = __sinl(x, 0, 0);
  33. *cos = __cosl(x, 0);
  34. return;
  35. }
  36. n = __rem_pio2l(x, y);
  37. s = __sinl(y[0], y[1], 1);
  38. c = __cosl(y[0], y[1]);
  39. switch (n & 3) {
  40. case 0:
  41. *sin = s;
  42. *cos = c;
  43. break;
  44. case 1:
  45. *sin = c;
  46. *cos = -s;
  47. break;
  48. case 2:
  49. *sin = -s;
  50. *cos = -c;
  51. break;
  52. case 3:
  53. default:
  54. *sin = -c;
  55. *cos = s;
  56. break;
  57. }
  58. }
  59. #endif