decimal icon indicating copy to clipboard operation
decimal copied to clipboard

sin() / cos() / tan() methods

Open mmstick opened this issue 6 years ago • 4 comments

The calculate crate would benefit from using d128 instead of f64 for calculating floats accurately. The ion shell uses calculate for it's built-in calc command. The methods above are required by calculate though, and are missing here.

mmstick avatar Oct 06 '17 22:10 mmstick

Unfortunately the underlying API does not support these ops so it is not easy to add. If you can provide implementations I would be happy to review them.

That aside why do you think d128 is going to be accurate? Is there something specific about sin/cos/tan that make them more accurate when arithmetic is done in decimal arithmetic and not binary? Perhaps you are looking for an arbitrary precision library?

alkis avatar Oct 12 '17 07:10 alkis

I've already gone ahead and switched the calculate crate to using d128, instead of f64, and it is more accurate. 0.1 * 0.1 actually equals 0.01, and not 0.010000000000000002. The bigdecimal crate is much further behind this one, so it's not an option at this time.

mmstick avatar Oct 12 '17 17:10 mmstick

Decimal floating point suffers from the same rounding issues as binary floating point. It's just that the decimal rounding issues tend to line up with how humans do things by hand. This doesn't mean that decimal floating point doesn't have surprising results. For example:

println!("{}", d128!(3.0) * (d128!(1.0) / d128!(3.0)));

outputs 0.9999999999999999999999999999999999.

Benjamin-L avatar Dec 13 '18 23:12 Benjamin-L

I think trigonometric functions would be best implemented in some other crate, since exactly what is required is strongly dependent on the application's needs for accuracy. It seems better if this crate remains a fairly thin binding to decNumber.

I've been looking into this for one of my own applications but haven't arrived at any particular conclusions for the best way to implement trig functions in terms of d128 (I am by no means an expert numeric analyst!). A Taylor series approximation is pretty easy to implement but might be very costly, and I suspect a different polynomial approximation would perform better. Iterative approximation (CORDIC) seems decent but I suspect it's not significantly more performant than implementations that are expressed in terms of multiplication because this library can take advantage of hardware multipliers to a certain degree.

tari avatar Jul 13 '22 05:07 tari