diff options
author | Joseph Myers <joseph@codesourcery.com> | 2015-10-02 17:11:13 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2015-10-02 17:11:13 +0000 |
commit | 59a63cca1133a8e1e3219970ee95979ac1f810df (patch) | |
tree | a4fc7c389f60647377479748d75bcc94f3c36547 /sysdeps/ieee754/ldbl-128 | |
parent | ef6b619f73e49b6d87c7530e6e9f8a59723b492d (diff) | |
download | glibc-59a63cca1133a8e1e3219970ee95979ac1f810df.tar.gz glibc-59a63cca1133a8e1e3219970ee95979ac1f810df.tar.xz glibc-59a63cca1133a8e1e3219970ee95979ac1f810df.zip |
Fix nexttoward overflow in non-default rounding modes (bug 19059).
ISO C requires overflowing results from nexttoward to be the appropriate infinity independent of the rounding mode, but some implementations use a rounding-mode-dependent result (this is the same issue as was fixed for nextafter in bug 16677). This patch fixes the problem by making the nexttoward implementations discard the result from the floating-point computation that forced an overflow exception and then return the infinity previously computed with integer arithmetic. Tested for x86_64, x86, mips64 and powerpc. [BZ #19059] * math/s_nexttowardf.c (__nexttowardf): Do not return value from overflowing computation. * sysdeps/i386/fpu/s_nexttoward.c (__nexttoward): Likewise. * sysdeps/i386/fpu/s_nexttowardf.c (__nexttowardf): Likewise. * sysdeps/ieee754/ldbl-128/s_nexttoward.c (__nexttoward): Likewise. * sysdeps/ieee754/ldbl-128/s_nexttowardf.c (__nexttowardf): Likewise. * sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c (__nexttoward): Likewise. * sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c (__nexttowardf): Likewise. * sysdeps/ieee754/ldbl-96/s_nexttoward.c (__nexttoward): Likewise. * sysdeps/ieee754/ldbl-96/s_nexttowardf.c (__nexttowardf): Likewise. * sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c (__nldbl_nexttowardf): Likewise. * math/libm-test.inc (nexttoward_test_data): Add more tests.
Diffstat (limited to 'sysdeps/ieee754/ldbl-128')
-rw-r--r-- | sysdeps/ieee754/ldbl-128/s_nexttoward.c | 4 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128/s_nexttowardf.c | 5 |
2 files changed, 6 insertions, 3 deletions
diff --git a/sysdeps/ieee754/ldbl-128/s_nexttoward.c b/sysdeps/ieee754/ldbl-128/s_nexttoward.c index e62ca3fef8..2ee7a1be5c 100644 --- a/sysdeps/ieee754/ldbl-128/s_nexttoward.c +++ b/sysdeps/ieee754/ldbl-128/s_nexttoward.c @@ -73,8 +73,8 @@ double __nexttoward(double x, long double y) } hy = hx&0x7ff00000; if(hy>=0x7ff00000) { - x = math_narrow_eval (x+x); /* overflow */ - return x; + double u = x+x; /* overflow */ + math_force_eval (u); } if(hy<0x00100000) { double u = x*x; /* underflow */ diff --git a/sysdeps/ieee754/ldbl-128/s_nexttowardf.c b/sysdeps/ieee754/ldbl-128/s_nexttowardf.c index ccd49d235d..9c9c7e5283 100644 --- a/sysdeps/ieee754/ldbl-128/s_nexttowardf.c +++ b/sysdeps/ieee754/ldbl-128/s_nexttowardf.c @@ -59,7 +59,10 @@ float __nexttowardf(float x, long double y) } } hy = hx&0x7f800000; - if(hy>=0x7f800000) return x+x; /* overflow */ + if(hy>=0x7f800000) { + float u = x+x; /* overflow */ + math_force_eval (u); + } if(hy<0x00800000) { float u = x*x; /* underflow */ math_force_eval (u); /* raise underflow flag */ |