dankogai / swift-bignum

Arbitrary-precision arithmetic for Swift, in Swift
MIT License
29 stars 8 forks source link

maxPrecision support? #2

Open dankogai opened 4 years ago

dankogai commented 4 years ago

From a mail I received

I want to use your BigNum Package to compute fractals with arbitrary Precision! However, I realised that the algorithm gets choked to death by every increasing precision floating point numbers (I use BigFloat). Is there a way to limit the precision of BigFloats. And more importantly to limit the precision of products or sums of big floats (e.g. to 100 digits?)?

I thought about something like:

var temp = BigFloat.init(maxPrecision:100)

Such that temp will get a limit, and thereby the CPU has a chance to perform….

dankogai commented 4 years ago

BigInt does support the notion of maximum precision.

import BigNum
BigFloat.precision // 64 by default
BigFloat.exp(1)      // 2.71828182845904523543
BigFloat.precision = 128
BigFloat.exp(1)      // 2.718281828459045235360287471352662497759
Double.exp(1)        // 2.7182818284590451

And each math function can manually set the precision of the result.

// 2.718281828459045235360287471352662497759 regardless of BigFloat.precision
BigFloat.exp(1, precision:128)

The problem is this applies only to math functions. For arithmetic operations +, - and *, precisions are not truncated because you can always yield exact results.

You can manually reduce precision via .truncate(width:) or .truncated(width:) .truncate(width:) mutates the current BigFloat object while `.truncated(width:) creates a new one.

let sqrt2 = BigFloat.sqrt(2, precision:128) // 1.414213562373095048801688724209698078569
sqrt2 * sqrt2 // 1.999999999999999999999999999999999999998088560099136799265635354844041733139597
(sqrt2 * sqrt2).truncated(width:128) // 2.0

The operation / already has a divide(by:precision:round:) and divided(by:precision:round:) which manually sets precision (with the rounding rule specified in round:). I should add .add{,ed}(), subtract{,ed}() .multipl{y,ed}(), that corresponds to the division…

mattRGB commented 4 years ago

Thanks for the clarification. I will use truncation to limit the precision.....