Skip to content

Trig/exp/log functions silently return under-precision (or wrong) digits once required working precision exceeds the 150-digit π/e/ln constants #96

Description

@matt-edmondson

What happens

PreciseNumber/PreciseNumber.cs, ConstantTo (~line 403-414); consumed by PiTo/ETo/Ln2To/Ln10To, and in turn by PreciseNumber/PreciseNumber.Trigonometry.cs (SinCos, SinCosPi, Atan2, DegreesToRadians/RadiansToDegrees) and PreciseNumber/PreciseNumber.Exponentials.cs (Log, Log10, Exp, FractionalPow, etc.).

Pi, E, Ln2, Ln10 are stored as fixed 150-digit literals (ConstantPrecision = 150, per #79). ConstantTo is:

return significantDigits >= constant.SignificantDigits ? constant : ...ReduceSignificance(...)

When a caller asks for more digits than 150, it silently hands back the unchanged 150-digit constant — no exception, no truncation warning, nothing to signal the requested precision wasn't met. Meanwhile the trig/exp code computes a working precision (e.g. reductionDigits = working + argumentDigits + TrigonometricGuardDigits) and assumes PiTo(reductionDigits) actually delivers that many digits — the code's own comments describe this requirement, but nothing enforces it.

Failure scenario

Calling Sin/Cos/Tan/Atan2/Log/Exp on any PreciseNumber whose own SignificantDigits is roughly ≥141 is enough to exceed 150 once guard digits are added (the repo's own benchmark suite standardizes on a 200-digit case). For an x whose integer magnitude also eats into that budget (e.g. the result of multiplying two ~80-digit values), the quadrant/argument reduction (x - quadrant·piOverTwo etc.) cancels more leading digits than the capped constant actually carries — so the digits returned past the cancellation point aren't just less precise, they can be outright wrong, while the result still reports SignificantDigits worth of digits as if they were trustworthy.

This is a "silent wrong answer" failure mode, similar in spirit to what #79 called "the expensive failure mode" — but here it's the reduction constant silently running out of budget rather than the constant itself being too short.

Suggested fix

In ConstantTo, throw a clear exception (e.g. NotSupportedException) when significantDigits > constant.SignificantDigits instead of silently returning the truncated constant, or add an explicit reductionDigits <= ConstantPrecision guard at each of the trig/exp reduction call sites that throws with a message naming the shortfall. At minimum this ceiling needs to be documented on Sin/Cos/Tan/Atan2/Log/Exp, since none of their current XML docs mention it.

Suggested acceptance criteria

  • A test requesting a trig/log/exp result at >150 total working digits (e.g. a ~145-digit input) either throws a clear, documented exception, or is proven to still return correct digits (if the ceiling is raised instead).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions