Skip to content

Pow and Exp never return more than 15 significant digits because they compute in double, though PreciseNumber now provides exact Exp/Pow #137

Open

Description

@matt-edmondson

What's wrong

Pow (SignificantNumber/SignificantNumber.cs:592-633) and Exp (:670-697) take a double path for every non-integer power and for integer powers above MaxExactIntegerPower (1024):

So the documented contract, "rounded to the fewest significant digits of the two", is in practice "at most 15 digits", however precise both operands are.

The referenced ktsu.PreciseNumber (2.6.x, Directory.Packages.props) has implemented IExponentialFunctions/IPowerFunctions since v2.4.0 (ktsu-dev/PreciseNumber#81). PreciseNumber.Exp(x, significantDigits) and PreciseNumber.Pow(x, y) (PreciseNumber.Exponentials.cs) compute to arbitrary width without going through double.

Failure scenario

Scratch MSTest on .NET 10 at f3c593d:

x = 0.12345678901234567891                     (20 significant digits; E has 150)
SignificantNumber.Exp(x)      = 1.1314011145262        (15 digits; trailing 0 trimmed)
PreciseNumber.Exp(x, 20)      = 1.1314011145262015187

b = 1.1234567890123456789, p = 2.5000000000000000001  (both 20 digits)
b.Pow(p)                      = 1.33779920191736       (15 digits)
PreciseNumber.Pow(b, p) @ 20  = 1.3377992019173604607

The same double pipeline is also the root cause of #116 (a base near 1 is wrong from the 3rd digit) and #117 ((-1).Pow(2E308) throws). #116 proposes double.LogP1 plus a further digit cap; this issue proposes removing the double dependency instead, which would fix all three.

Suggested fix

  • Compute the non-exact paths of Pow and Exp with PreciseNumber.Pow/PreciseNumber.Exp at the target significant digits plus a few guard digits, then ReduceSignificance to the target.
  • Drop CapToExponentPrecision, FromLog10OfMagnitude and Log10OfMagnitude where no longer needed.
  • Keep the exact integer-power path for |n| ≤ 1024.

Acceptance criteria

Activity

  1. matt-edmondson commented on Oct 20, 2026

    @matt-edmondson
    ContributorAuthor

    Triage


    Generated by Claude Code

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

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions