noncephes.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * This file contains math functions missing from the Cephes library.
  3. *
  4. * May 22, 2001 Manuel Novoa III
  5. *
  6. * Added modf and fmod.
  7. *
  8. * TODO:
  9. * Break out functions into seperate object files as is done
  10. * by (for example) stdio. Also do this with cephes files.
  11. */
  12. #include <math.h>
  13. #include <errno.h>
  14. #undef UNK
  15. /* Set this to nonzero to enable a couple of shortcut tests in fmod. */
  16. #define SPEED_OVER_SIZE 0
  17. /**********************************************************************/
  18. double modf(double x, double *iptr)
  19. {
  20. double y;
  21. #ifdef UNK
  22. mtherr( "modf", DOMAIN );
  23. *iptr = NAN;
  24. return NAN;
  25. #endif
  26. #ifdef NANS
  27. if( isnan(x) ) {
  28. *iptr = x;
  29. return x;
  30. }
  31. #endif
  32. #ifdef INFINITIES
  33. if(!isfinite(x)) {
  34. *iptr = x; /* Matches glibc, but returning NAN */
  35. return 0; /* makes more sense to me... */
  36. }
  37. #endif
  38. if (x < 0) { /* Round towards 0. */
  39. y = ceil(x);
  40. } else {
  41. y = floor(x);
  42. }
  43. *iptr = y;
  44. return x - y;
  45. }
  46. /**********************************************************************/
  47. extern double NAN;
  48. double fmod(double x, double y)
  49. {
  50. double z;
  51. int negative, ex, ey;
  52. #ifdef UNK
  53. mtherr( "fmod", DOMAIN );
  54. return NAN;
  55. #endif
  56. #ifdef NANS
  57. if( isnan(x) || isnan(y) ) {
  58. errno = EDOM;
  59. return NAN;
  60. }
  61. #endif
  62. if (y == 0) {
  63. errno = EDOM;
  64. return NAN;
  65. }
  66. #ifdef INFINITIES
  67. if(!isfinite(x)) {
  68. errno = EDOM;
  69. return NAN;
  70. }
  71. #if SPEED_OVER_SIZE
  72. if(!isfinite(y)) {
  73. return x;
  74. }
  75. #endif
  76. #endif
  77. #if SPEED_OVER_SIZE
  78. if (x == 0) {
  79. return 0;
  80. }
  81. #endif
  82. negative = 0;
  83. if (x < 0) {
  84. negative = 1;
  85. x = -x;
  86. }
  87. if (y < 0) {
  88. y = -y;
  89. }
  90. frexp(y,&ey);
  91. while (x >= y) {
  92. frexp(x,&ex);
  93. z = ldexp(y,ex-ey);
  94. if (z > x) {
  95. z /= 2;
  96. }
  97. x -= z;
  98. }
  99. if (negative) {
  100. return -x;
  101. } else {
  102. return x;
  103. }
  104. }