Skip to content

pi, e and a cached Evaled keep the digits of the first precision context they were evaluated under #1367

Description

@Rafael-SOWNet

pi and e evaluate to the digits of whichever precision was active the first time, and an entity's cached Evaled survives a change of DecimalPrecisionContext, so the second evaluation of the same expression at a higher precision comes back at the lower one.

var x = Entity.Number.Real.Create(EDecimal.FromString("0.37000000000001234"));
Console.WriteLine(MathS.Pow(MathS.e, x).EvalNumerical());          // 100 digits, fine
using var _ = MathS.Settings.DecimalPrecisionContext.Set(new EContext(300, ERounding.HalfUp, -5000, 5000, false));
Console.WriteLine(MathS.Pow(MathS.e, x).EvalNumerical());          // 300 digits printed, correct to 100
Console.WriteLine(MathS.pi.EvalNumerical());                       // 100 digits
e^x @300: 1.44773461466334232662989728105331289895496596773489097124803337711872719737828089689049983122563626107283473223875807838789133356401920243391619994031014006811744887921117408767884324026066523691904514437945327933912855062295521809782890868042690728921407737563369064948398646175409204226875742995396
mpmath  : 1.4477346146633423266298972810533128989549659677348909712480333771187271973782808968904998312256362611570708175918866347464490548332052196352156710435710332682587883217473960307622422354384764392652386915303661697273096380952633917033052762392317525332683262721013424903315670646133049105751036966520970031
                                                                                                            ^ digit 101
pi @300:  3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068

Two causes:

  1. Variable.ConstantList is a static dictionary of Complex built once from MathS.DecimalConst.pi/.e, which read the context current at class initialisation; Constant.Value returns that forever. A pi first touched at 500 digits then answers 500 digits in a 100-digit context too (the other direction of the same defect).
  2. Entity.Evaled is cached on the instance with no notion of the precision it was computed under. MathS.pi and MathS.e are one object each by design (a binder recognises them by reference), so their cache is process-wide; but any held instance has the same problem — var s = MathS.Sin(1); s.EvalNumerical(); at 100 digits and again at 500 gives the 100-digit value.

The second is also why e^x above is wrong rather than merely stale: the base e no longer equals the cache's 300-digit E, so Pow falls from "the exponential of the power" to PowerOfReals — a logarithm of a 100-digit base and an exponential, at 300 digits.

Fix I am taking: the constant's value looked up at the current context on each evaluation, and an evaluation epoch — a counter the precision setting bumps on every Set and on every scope's end — recorded on the entity beside its Evaled and compared on each read, so a cached evaluation under another precision is recomputed. One int per entity and one static read per Evaled; the gate will say what that costs. Found while measuring #1338.

Activity

  1. added a commit that references this issue on Sep 16, 2026
    01fa27b
  2. added theissue type on Sep 22, 2026
  3. added this to the 2.6.0 milestone on Oct 9, 2026
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

    No labels
    No labels

    Type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions