gcc/libquadmath/math
Jakub Jelinek e081ced345 libquadmath: Fix up THREEp96 constant in expq
Here is a cherry-pick from glibc [BZ #32411] fix.

As mentioned by the reporter in a pull request against gcc-mirror,
the THREEp96 constant in e_expl.c is incorrect, it is actually 0x3.p+94f128
rather than 0x3.p+96f128.

The algorithm uses that to compute the t2 integer (tval2), by whose
delta it adjusts the x+xl pair and then in the result uses the precomputed
exp value for that entry.
Using 0x3.p+94f128 rather than 0x3.p+96f128 results in tval2 sometimes
being one smaller, sometimes one larger than the desired value, thus can mean
the x+xl pair after adjustment will be larger in absolute value than it
should be.

DesWursters created a test program for this
https://github.com/DesWurstes/comparefloats
and his results were
total: 1135000000 not_equal: 4322 earlier_score: 674 later_score: 3648
I've modified this so with
https://sourceware.org/bugzilla/show_bug.cgi?id=32411#c3
so that it actually tests pseudo-random _Float128 values with range
(-16384.,16384) with strong bias on values larger than 0.0002 in absolute
value (so that tval1/tval2 aren't zero most of the time) and that gave
total: 10000000000 not_equal: 29861 earlier_score: 4606 later_score: 25255
So, in both cases, in most cases the change doesn't result in any differences,
and in those rare cases where does, about 85% have smaller ulp than without
the patch.
Additionally I've tried
https://sourceware.org/bugzilla/show_bug.cgi?id=32411#c4
and in 2 billion iterations it didn't find any case where x+xl after the
adjustments without this change would be smaller in absolute value compared
to x+xl after the adjustments with this change.

2025-04-09  Jakub Jelinek  <jakub@redhat.com>

	* math/expq.c (C): Fix up THREEp96 constant.
2025-04-09 22:09:15 +02:00
..
acoshq.c
acosq.c
asinhq.c
asinq.c
atan2q.c
atanhq.c
atanq.c
cacoshq.c
cacosq.c
casinhq.c
casinhq_kernel.c
casinq.c
catanhq.c
catanq.c
cbrtq.c
ccoshq.c
ceilq.c
cexpq.c
cimagq.c
clog10q.c
clogq.c
complex.c
conjq.c
copysignq.c
coshq.c
cosq.c
cosq_kernel.c
cprojq.c
crealq.c
csinhq.c
csinq.c
csqrtq.c
ctanhq.c
ctanq.c
erfq.c
exp2q.c
expm1q.c
expq.c libquadmath: Fix up THREEp96 constant in expq 2025-04-09 22:09:15 +02:00
expq_table.h
fabsq.c
fdimq.c
finiteq.c
floorq.c
fmaq.c
fmaxq.c
fminq.c
fmodq.c
frexpq.c
hypotq.c
ilogbq.c
isinfq.c
isnanq.c
issignalingq.c
j0q.c
j1q.c
jnq.c
ldexpq.c
lgammaq.c
lgammaq_neg.c
lgammaq_product.c
llrintq.c
llroundq.c
log1pq.c
log2q.c
log10q.c
logbq.c
logq.c
lrintq.c
lroundq.c
modfq.c
nanq.c
nearbyintq.c
nextafterq.c
powq.c
rem_pio2q.c
remainderq.c
remquoq.c
rintq.c
roundq.c
scalblnq.c
scalbnq.c
signbitq.c
sincos_table.c
sincosq.c
sincosq_kernel.c
sinhq.c
sinq.c
sinq_kernel.c
sqrtq.c
tanhq.c
tanq.c
tanq_kernel.c
tgammaq.c
tgammaq_product.c
truncq.c
x2y2m1q.c