s_nearbyint.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536
  1. #include <limits.h>
  2. #include <math.h>
  3. /*******************************************************************************
  4. * *
  5. * The function nearbyint rounds its double argument to integral value *
  6. * according to the current rounding direction and returns the result in *
  7. * double format. This function does not signal inexact. *
  8. * *
  9. ********************************************************************************
  10. * *
  11. * This function calls fabs and copysign. *
  12. * *
  13. *******************************************************************************/
  14. static const double twoTo52 = 4503599627370496.0;
  15. double nearbyint ( double x )
  16. {
  17. double y;
  18. double OldEnvironment;
  19. y = twoTo52;
  20. asm ("mffs %0" : "=f" (OldEnvironment)); /* get the environement */
  21. if ( fabs ( x ) >= y ) /* huge case is exact */
  22. return x;
  23. if ( x < 0 ) y = -y; /* negative case */
  24. y = ( x + y ) - y; /* force rounding */
  25. if ( y == 0.0 ) /* zero results mirror sign of x */
  26. y = copysign ( y, x );
  27. // restore old flags
  28. asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment ));
  29. return ( y );
  30. }