diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/s_llround.c | 33 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/s_llroundf.c | 33 |
3 files changed, 37 insertions, 34 deletions
diff --git a/ChangeLog b/ChangeLog index 9d2d856729..6bfeb63aaa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2013-10-04 Alan Modra <amodra@gmail.com> + * sysdeps/powerpc/fpu/s_llround.c (__llround): Rewrite. + * sysdeps/powerpc/fpu/s_llroundf.c (__llroundf): Rewrite. + +2013-10-04 Alan Modra <amodra@gmail.com> + * sysdeps/powerpc/fpu/s_float_bitwise.h (__float_and_test28): Don't use vector int constants. (__float_and_test24, __float_and8, __float_get_exp): Likewise. diff --git a/sysdeps/powerpc/fpu/s_llround.c b/sysdeps/powerpc/fpu/s_llround.c index 9a01826539..995d0a724a 100644 --- a/sysdeps/powerpc/fpu/s_llround.c +++ b/sysdeps/powerpc/fpu/s_llround.c @@ -19,29 +19,28 @@ #include <math.h> #include <math_ldbl_opt.h> -/* I think that what this routine is supposed to do is round a value - to the nearest integer, with values exactly on the boundary rounded - away from zero. */ -/* This routine relies on (long long)x, when x is out of range of a long long, - clipping to MAX_LLONG or MIN_LLONG. */ +/* Round to the nearest integer, with values exactly on a 0.5 boundary + rounded away from zero, regardless of the current rounding mode. + If (long long)x, when x is out of range of a long long, clips at + LLONG_MAX or LLONG_MIN, then this implementation also clips. */ long long int __llround (double x) { - double xrf; - long long int xr; - xr = (long long int) x; - xrf = (double) xr; + long long xr = (long long) x; + double xrf = (double) xr; + if (x >= 0.0) - if (x - xrf >= 0.5 && x - xrf < 1.0 && x+1 > 0) - return x+1; - else - return x; + { + if (x - xrf >= 0.5) + xr += (long long) ((unsigned long long) xr + 1) > 0; + } else - if (xrf - x >= 0.5 && xrf - x < 1.0 && x-1 < 0) - return x-1; - else - return x; + { + if (xrf - x >= 0.5) + xr -= (long long) ((unsigned long long) xr - 1) < 0; + } + return xr; } weak_alias (__llround, llround) #ifdef NO_LONG_DOUBLE diff --git a/sysdeps/powerpc/fpu/s_llroundf.c b/sysdeps/powerpc/fpu/s_llroundf.c index 07d12adbfb..0935de6624 100644 --- a/sysdeps/powerpc/fpu/s_llroundf.c +++ b/sysdeps/powerpc/fpu/s_llroundf.c @@ -18,28 +18,27 @@ #include <math.h> -/* I think that what this routine is supposed to do is round a value - to the nearest integer, with values exactly on the boundary rounded - away from zero. */ -/* This routine relies on (long long)x, when x is out of range of a long long, - clipping to MAX_LLONG or MIN_LLONG. */ +/* Round to the nearest integer, with values exactly on a 0.5 boundary + rounded away from zero, regardless of the current rounding mode. + If (long long)x, when x is out of range of a long long, clips at + LLONG_MAX or LLONG_MIN, then this implementation also clips. */ long long int __llroundf (float x) { - float xrf; - long long int xr; - xr = (long long int) x; - xrf = (float) xr; + long long xr = (long long) x; + float xrf = (float) xr; + if (x >= 0.0) - if (x - xrf >= 0.5 && x - xrf < 1.0 && x+1 > 0) - return x+1; - else - return x; + { + if (x - xrf >= 0.5) + xr += (long long) ((unsigned long long) xr + 1) > 0; + } else - if (xrf - x >= 0.5 && xrf - x < 1.0 && x-1 < 0) - return x-1; - else - return x; + { + if (xrf - x >= 0.5) + xr -= (long long) ((unsigned long long) xr - 1) < 0; + } + return xr; } weak_alias (__llroundf, llroundf) |