|
|
|
# commit da13146da10360436941e843834c90a9aef5fd7a
|
|
|
|
# Author: Alan Modra <amodra@gmail.com>
|
|
|
|
# Date: Sat Aug 17 18:30:23 2013 +0930
|
|
|
|
#
|
|
|
|
# PowerPC floating point little-endian [10 of 15]
|
|
|
|
# http://sourceware.org/ml/libc-alpha/2013-07/msg00201.html
|
|
|
|
#
|
|
|
|
# These two functions oddly test x+1>0 when a double x is >= 0.0, and
|
|
|
|
# similarly when x is negative. I don't see the point of that since the
|
|
|
|
# test should always be true. I also don't see any need to convert x+1
|
|
|
|
# to integer rather than simply using xr+1. Note that the standard
|
|
|
|
# allows these functions to return any value when the input is outside
|
|
|
|
# the range of long long, but it's not too hard to prevent xr+1
|
|
|
|
# overflowing so that's what I've done.
|
|
|
|
#
|
|
|
|
# (With rounding mode FE_UPWARD, x+1 can be a lot more than what you
|
|
|
|
# might naively expect, but perhaps that situation was covered by the
|
|
|
|
# x - xrf < 1.0 test.)
|
|
|
|
#
|
|
|
|
# * sysdeps/powerpc/fpu/s_llround.c (__llround): Rewrite.
|
|
|
|
# * sysdeps/powerpc/fpu/s_llroundf.c (__llroundf): Rewrite.
|
|
|
|
#
|
|
|
|
diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llround.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llround.c
|
|
|
|
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llround.c 2014-05-27 22:38:55.000000000 -0500
|
|
|
|
+++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llround.c 2014-05-27 22:38:58.000000000 -0500
|
|
|
|
@@ -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 -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llroundf.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llroundf.c
|
|
|
|
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llroundf.c 2014-05-27 22:38:55.000000000 -0500
|
|
|
|
+++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llroundf.c 2014-05-27 22:38:58.000000000 -0500
|
|
|
|
@@ -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)
|