Preserve the nearbyint implementation and regression coverage while incorporating current main. The write-watch registration prerequisite is now part of main.
Validation: freshly compiled production MathExact.cpp regression passes; ASan/UBSan passes with detect_leaks=0. The same fixture compiles against main Math.cpp and fails at the FE_INEXACT assertion (exit 134). Conventions, whitespace and 235 script registrations pass. Full product build and full CTest were not rerun for this synchronization.
exp returned the host's exp, whose last bit differs from the titles' copy on
Windows on 9,892,285 of 320 million random arguments. The titles' copy is
FreeBSD msun's e_exp.c, except that exp(1) returns the correctly rounded e,
and it sets ERANGE only in msun's overflow and underflow branches. exp now
computes that and sets ERANGE there.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
wcstod parsed through the host strtod directly, so a decimal input with
a nonzero subnormal result left errno alone, where strtod sets ERANGE.
The wcstod of the libc.prx bundled with eleven titles sets it in the
same cases as their strtod: 1e-310, the smallest subnormal and 1e-330
set it, 2.2250738585072014e-308 and 0x1p-1074 do not, and 0x1.8p-1075
does. wcstod now parses through strtod.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The titles' scalbn and scalbnf never set errno, at any exponent. On
Windows the host scalbn already matches, but glibc's scalbn and scalbnf
set ERANGE on overflow and on underflow to zero (found by rooklz while
reviewing #12676), so on Linux they did. Both now keep errno across the
host call, as scalbln and scalblnf already do. CheckScalbnErrno checks
results read from the titles' libc.prx.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
ldexpf called the host ldexp on a float, which computes in double and
sets ERANGE only when the double result leaves the double range, so
ldexpf(0x1.3d1c6p-95f, 1262) set ERANGE while ldexpf(1.0f, 200) did
not. The titles' ldexpf never sets errno, as their scalbnf does not.
ldexpf now computes like scalbnf: on 100,000 random arguments it
matches the libc.prx of PPSA07923 and PPSA05916 in every value and
errno, against 63,957 errno differences before.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The pow of the libc.prx that titles ship (PPSA07923) multiplies |x| by
2^53 for its subnormal normalization on every general-path call and
keeps the product only for subnormal x. For |x| from 2^971 up the
unused product overflows, so pow raises FE_OVERFLOW there for any
exponent that reaches the general path, even when the result is
finite (pow(1e300, -0.25)). The product is now computed the same way;
it is exact below 2^971, so only that flag changes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2^-149 and -2^-141 are exact subnormal powf results that raise no flag,
and 3^-90 is an inexact one that raises FE_UNDERFLOW and FE_INEXACT;
none sets errno, as in the libc.prx of PPSA07923 and PPSA13934.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Titles' libc.prx raises FE_INVALID wherever log10 stores EDOM, a NaN
argument included, where (x - x) / zero raised nothing for a NaN
operand. The domain path now raises through _Feraise, which stores EDOM
and raises the flag in both units. For +-0 it now returns -inf without raising FE_DIVBYZERO, as the titles do; the port divided -two54 by zero.
Results and errno are unchanged. CheckLog10EdgeFlags covers it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
log10 returned the host's log10, whose last bit differs from the titles'
copy on Windows on 3,066,397 of 320 million random arguments. The titles'
copy is the fdlibm e_log10.c over its k_log.h, which FreeBSD 11.4 later
replaced, and it sets EDOM for every nonzero argument with the sign bit set
but leaves errno alone for +-0. log10 now computes that and sets EDOM there.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Titles' libc.prx raises FE_UNDERFLOW and FE_INEXACT when pow underflows
for 2^31 < |y| <= 2^64 and at the final range check, and raises nothing
for |y| > 2^64, where its huge * huge and tiny * tiny were folded into
constants. Here GCC folded every tiny * tiny product, so no underflow
flag was raised, while huge * huge for |y| > 2^64 raised FE_OVERFLOW.
Return +inf directly for |y| > 2^64 and compute the other underflowing
products through a volatile, so the flags match on every path. Results
and errno are unchanged. CheckPowRangeFlags covers each path.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
pow returned the host's pow, whose last bit differs from the titles' copy on
Windows on 17,275,531 of 320 million random pairs, and which follows C99
for pow(1, NaN) and pow(-1, +-inf) where the titles' copy returns NaN. The
titles' copy is FreeBSD msun's e_pow.c with those two original fdlibm
rules. It sets EDOM where a negative base meets a non-integer exponent and
ERANGE only in the final overflow and underflow checks. pow now computes
that and sets errno there.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Titles' libc.prx raises FE_INVALID wherever log2 and log10 stores EDOM, a NaN
argument included, where (x - x) / zero raised nothing for a NaN
operand. The domain path now raises through _Feraise, which stores EDOM
and raises the flag in both units. For +-0 it now returns -inf without raising FE_DIVBYZERO, as the titles do; the port divided -two54 by zero.
Results and errno are unchanged. CheckLog2EdgeFlags and CheckLog10EdgeFlags cover it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>