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.
119 lines
4.2 KiB
119 lines
4.2 KiB
# 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)
|
|
|