Reputation: 89713
Hi all I was wondering is there a class in .Net that is used to calculate precise numbers with no rounding errors?
For example, this is not what I want:
decimal dividend = Decimal.One;
decimal divisor = 3;
dividend/divisor * divisor // gives us 0.9999999999999999999999999999 instead of 1
I was thinking if there is a number class that buffers operation until when we need to display it, in other words it would look like this:
Num n = new Num(1);
n.DivideBy(3);
n.MultiplyBy(3);
n.toString(); // gives us "1"
Num n2 = new Num(n);
n2.DivideBy(3);
int decimal_places = 8;
n2.RoundHalfUp(decimal_places);
n2.toString(); // gives us "0.33333333"
Of course this is just an example implementation. Basically the main point here is I'm searching for a class that does not have any rounding errors (usually by delaying calculations to the last moment).
I understand that performance would be slower than Double
or Decimal
. But it doesn't have to do calculations blindly fast, as long as it is within acceptable time.
Upvotes: 2
Views: 202
Reputation: 244918
Your specific problem could be solved by a type that can represent any fraction exactly. You can use a library for that or write one yourself (it shouldn't be that hard).
But if you want to solve the general problem, so that Math.Pow(Math.Sqrt(2), 2) == 2
returns true
and that works for arbitrary operations, you would need a type that can represent any calculation and be able to reliably simplify it. Just delaying the calculation isn't enough.
I'm not sure something like this exists or that it's even possible.
Upvotes: 1
Reputation: 56976
This is a job for rational numbers. No need to delay anything if you're only doing arithmetic operations (including division).
If you need to compute arbitrary continuous functions (eg. logarithms, cosines, square roots, etc), it becomes way more involved. Keeping track of the needed digits to ensure requested precision is tricky, but definitely doable, albeit inefficient in practice. The idea is to store along each function another function computing a modulus of continuity (you get what one would call "intuitionistic continuous functions").
Note that storing an expression tree doesn't simplify matters much, since you'll need to evaluate the resulting (hopefully simpler) expression.
Another approach would be to store a power series along with a radius of convergence, and compute the sum of the series when requested.
Upvotes: 7
Reputation: 8996
Perhaps an arbitrary precision integer library would be sufficient for your needs?
The linked answer deals with C#, but of course they are really general .NET answers.
Upvotes: 0