Skip to content

Sin/Cos/SinCos/Tan at default precision throw ArgumentOutOfRangeException on the library's own constants (e.g. Sin(PreciseNumber.Pi)) #124

Description

@matt-edmondson

What's wrong

The overloads that take no precision (Sin(x), Cos(x), SinCos(x), Tan(x), in PreciseNumber/PreciseNumber.Trigonometry.cs:101-102, 129-130, 157-158, 220-221) use DefaultTrigonometricPrecision(x) (line 736), which returns max(x.SignificantDigits, 50).

The built-in constants carry ConstantPrecision (150) digits and have one integer digit. For them the default asks for 150 digits, and reducing a one-integer-digit argument to 150 digits needs π to 151 digits. RequireReducibleArgument then throws. In other words, the overload that picks its own precision picks one it will refuse.

This contradicts two pieces of documentation:

  • The XML docs for these overloads promise the result is "produced to the significant digits of x" and list no ArgumentOutOfRangeException.
  • The remark on DefaultTrigonometricPrecision says it exists so that a constant carrying ConstantPrecision digits is handled.

Reproduction

Sin(PreciseNumber.Pi) → ArgumentOutOfRangeException: Reducing an argument of 1 integer digits to 150 significant digits needs π to 151 digits, but it is stored to 150. At most 149 …
Cos(Pi), Cos(Tau), Sin(E), SinCos(Pi) → same exception
Sin(Ln2) → works (0 integer digits)
Exp(Pi), Log(Pi), Pow(Pi, E), Sinh(Pi), Atan(Pi), Atan2(Pi, E), Asin(Pi/4) → all work at 150 digits

The same exception is thrown for any computed value that has at least 150 significant digits and at least one integer digit, for example a quotient or root of two constants.

Why it matters

Math.Sin(Math.PI)-style code is the most basic use of the API, and every other transcendental function handles these inputs. Callers can't predict which values will throw without knowing the internal ceiling on π digits.

Suggested fix

Related: Tan's guard digits make the ceiling even lower for Tan, which I'm filing separately.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingreadyFully specified; implement as written

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions