"""REGRESSION, 2026-09-21: sign tests by product underflowed on flat functions. `FA * fnew < 0.0` with FA ~ -1e-200 and fnew ~ 1e-150 is -0.0, and '-0.0 < 0.0' is False: the bracket update moved the wrong end, the root left the bracket, and the run still reported convergence - on fun6.5 (x^19 over [-10, 100]) the proposed rule returned 6.7e-9 and a lengthening mode 1.27e-6 with a claimed 1e-12 bracket. The same product test sat in our bisection, false-position family, Ridders, Brent and ITP. """ from __future__ import annotations import pytest from simroot.baselines import (_opposite, _same_sign, bisection, illinois, itp, regula_falsi, ridders) from simroot.pure import pure_root XTOL, MAXFEV = 1e-12, 200 def test_the_product_underflows_and_the_sign_test_does_not(): u, v = -1e-200, 1e-150 assert u * v == 0.0 # the defect, pinned assert _opposite(u, v) and not _same_sign(u, v) assert _same_sign(-1e-200, -1e-150) and not _opposite(-1e-200, -1e-150) assert not _opposite(0.0, 1.0) and not _same_sign(0.0, 1.0) def power19(t): return t ** 19 @pytest.mark.parametrize("guard", ("project", "safe", "credit", "none")) @pytest.mark.parametrize("extrapolate", ("none", "confirmed")) def test_the_method_keeps_the_root_in_the_bracket_on_x19(guard, extrapolate): for sim in ("ratio", "cbrt"): x, n, ok = pure_root(power19, -10.0, 100.0, XTOL, MAXFEV, similarity=sim, scale="derived3", guard=guard, extrapolate=extrapolate) if ok: assert abs(x) <= XTOL, (sim, guard, extrapolate, x) @pytest.mark.parametrize("method", (bisection, regula_falsi, illinois, ridders, itp)) def test_the_classical_methods_keep_the_root_on_x19(method): x, n, ok = method(power19, -10.0, 100.0, XTOL, MAXFEV) if ok: assert abs(x) <= XTOL, (method.__name__, x)