Mercurial > hg > CbC > CbC_gcc
diff libquadmath/math/x2y2m1q.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 04ced10e8804 |
children |
line wrap: on
line diff
--- a/libquadmath/math/x2y2m1q.c Thu Oct 25 07:37:49 2018 +0900 +++ b/libquadmath/math/x2y2m1q.c Thu Feb 13 11:34:05 2020 +0900 @@ -1,5 +1,5 @@ /* Compute x^2 + y^2 - 1, without large cancellation error. - Copyright (C) 2012 Free Software Foundation, Inc. + Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,7 +17,6 @@ <http://www.gnu.org/licenses/>. */ #include "quadmath-imp.h" -#include <stdlib.h> /* Calculate X + Y exactly and store the result in *HI + *LO. It is given that |X| >= |Y| and the values are small enough that no @@ -31,18 +30,6 @@ *lo = (x - *hi) + y; } -/* Calculate X * Y exactly and store the result in *HI + *LO. It is - given that the values are small enough that no overflow occurs and - large enough (or zero) that no underflow occurs. */ - -static inline void -mul_split (__float128 *hi, __float128 *lo, __float128 x, __float128 y) -{ - /* Fast built-in fused multiply-add. */ - *hi = x * y; - *lo = fmaq (x, y, -*hi); -} - /* Compare absolute values of floating-point values pointed to by P and Q for qsort. */ @@ -60,34 +47,26 @@ } /* Return X^2 + Y^2 - 1, computed without large cancellation error. - It is given that 1 > X >= Y >= epsilon / 2, and that either X >= - 0.75 or Y >= 0.5. */ + It is given that 1 > X >= Y >= epsilon / 2, and that X^2 + Y^2 >= + 0.5. */ __float128 __quadmath_x2y2m1q (__float128 x, __float128 y) { - __float128 vals[4]; - size_t i; - - /* FIXME: SET_RESTORE_ROUNDL (FE_TONEAREST); */ - mul_split (&vals[1], &vals[0], x, x); - mul_split (&vals[3], &vals[2], y, y); - if (x >= 0.75Q) - vals[1] -= 1.0Q; - else - { - vals[1] -= 0.5Q; - vals[3] -= 0.5Q; - } - qsort (vals, 4, sizeof (__float128), compare); + __float128 vals[5]; + SET_RESTORE_ROUNDF128 (FE_TONEAREST); + mul_splitq (&vals[1], &vals[0], x, x); + mul_splitq (&vals[3], &vals[2], y, y); + vals[4] = -1; + qsort (vals, 5, sizeof (__float128), compare); /* Add up the values so that each element of VALS has absolute value at most equal to the last set bit of the next nonzero element. */ - for (i = 0; i <= 2; i++) + for (size_t i = 0; i <= 3; i++) { add_split (&vals[i + 1], &vals[i], vals[i + 1], vals[i]); - qsort (vals + i + 1, 3 - i, sizeof (__float128), compare); + qsort (vals + i + 1, 4 - i, sizeof (__float128), compare); } /* Now any error from this addition will be small. */ - return vals[3] + vals[2] + vals[1] + vals[0]; + return vals[4] + vals[3] + vals[2] + vals[1] + vals[0]; }