summaryrefslogtreecommitdiff
path: root/libm/powerpc/s_nearbyint.c
diff options
context:
space:
mode:
Diffstat (limited to 'libm/powerpc/s_nearbyint.c')
-rw-r--r--libm/powerpc/s_nearbyint.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/libm/powerpc/s_nearbyint.c b/libm/powerpc/s_nearbyint.c
new file mode 100644
index 000000000..f2d7ded35
--- /dev/null
+++ b/libm/powerpc/s_nearbyint.c
@@ -0,0 +1,36 @@
+#include <limits.h>
+#include <math.h>
+
+/*******************************************************************************
+* *
+* The function nearbyint rounds its double argument to integral value *
+* according to the current rounding direction and returns the result in *
+* double format. This function does not signal inexact. *
+* *
+********************************************************************************
+* *
+* This function calls fabs and copysign. *
+* *
+*******************************************************************************/
+
+static const double twoTo52 = 4503599627370496.0;
+
+double nearbyint ( double x )
+ {
+ double y;
+ double OldEnvironment;
+
+ y = twoTo52;
+
+ asm ("mffs %0" : "=f" (OldEnvironment)); /* get the environement */
+
+ if ( fabs ( x ) >= y ) /* huge case is exact */
+ return x;
+ if ( x < 0 ) y = -y; /* negative case */
+ y = ( x + y ) - y; /* force rounding */
+ if ( y == 0.0 ) /* zero results mirror sign of x */
+ y = copysign ( y, x );
+// restore old flags
+ asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment ));
+ return ( y );
+ }