Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 lines
2.3 KiB

  1. /***
  2. *modf.c - modf()
  3. *
  4. * Copyright (c) 1991-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *
  8. *Revision History:
  9. * 8-24-91 GDP written
  10. * 1-13-92 GDP support IEEE exceptions
  11. * 6-23-92 GDP modified special return values for NCEG conformance
  12. * 02-06-95 JWM Mac merge
  13. * 01-26-01 PML Pentium4 merge
  14. * 02-28-01 PML Make sure 0.0 fraction return has correct sign
  15. *
  16. *******************************************************************************/
  17. #include <math.h>
  18. #include <trans.h>
  19. #include <float.h>
  20. extern double _frnd(double);
  21. extern double _copysign (double x, double y);
  22. /***
  23. *double modf(double x, double *intptr)
  24. *
  25. *Purpose:
  26. * Split x into fractional and integer part
  27. * The signed fractional portion is returned
  28. * The integer portion is stored as a floating point value at intptr
  29. *
  30. *Entry:
  31. *
  32. *Exit:
  33. *
  34. *Exceptions:
  35. * I
  36. *******************************************************************************/
  37. static uintptr_t newcw = (ICW & ~IMCW_RC) | (IRC_CHOP & IMCW_RC);
  38. #if !defined(_M_IX86)
  39. double modf(double x, double *intptr)
  40. #else
  41. double _modf_default(double x, double *intptr)
  42. #endif
  43. {
  44. uintptr_t savedcw;
  45. double result,intpart;
  46. /* save user fp control word */
  47. savedcw = _ctrlfp(0, 0); /* get old control word */
  48. _ctrlfp(newcw,IMCW); /* round towards 0 */
  49. /* check for infinity or NAN */
  50. if (IS_D_SPECIAL(x)){
  51. *intptr = QNAN_MODF;
  52. switch (_sptype(x)) {
  53. case T_PINF:
  54. case T_NINF:
  55. *intptr = x;
  56. result = _copysign(0, x);
  57. RETURN(savedcw,result);
  58. case T_QNAN:
  59. *intptr = x;
  60. return _handle_qnan1(OP_MODF, x, savedcw);
  61. default: //T_SNAN
  62. result = _s2qnan(x);
  63. *intptr = result;
  64. return _except1(FP_I, OP_MODF, x, result, savedcw);
  65. }
  66. }
  67. intpart = _frnd(x); //fix needed: this may set the P exception flag
  68. //and pollute the fp status word
  69. *intptr = intpart;
  70. result = x - intpart;
  71. if (result == 0.0) {
  72. /* Make sure fractional part of 0.0 has the correct sign */
  73. *D_EXP(result) |= (*D_EXP(x) & 0x8000);
  74. }
  75. RETURN(savedcw,result);
  76. }