Skip to content

bug(discrete): NegativeBinomial / Geometric getQuantile silently returns 0 once the search bound mean + 10σ + 100 exceeds INT_MAX #116

Description

@OldCrow

Severity: MED. Found by the 2026-08-21 defensive review (SV3), probe-verified against the shipped library.

src/negative_binomial.cpp:~320 computes the bisection upper bound as a double and casts it to int unguarded. For small p or large r the bound exceeds INT_MAX: on x86 the cast yields INT_MIN, the search range collapses and every quantile returns 0Geometric(1e-9).getQuantile(0.5) returns 0 where the answer is 6.93e8 (the CDF at the returned value is 1e-9, not 0.5); on AArch64 the cast saturates to 2.1e9 and the answer is capped. The one member of the double→int cast family (S6) that produces a wrong answer rather than a formally-UB-but-correct one.

Fix: widen the search bound to std::int64_t (or keep it in double and bisect on doubles), clamp before any narrowing; test: CDF(quantile(q)) ≈ q for Geometric(1e-9) at q ∈ {0.5, 0.99} and NegativeBinomial(1e10, 0.5); fails today.

Metadata

Metadata

Assignees

No one assigned

    Labels

    accuracybugSomething isn't working

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions