Giter Site home page Giter Site logo

decimalmath's Introduction

Decimal Math

Portable math support for Decimal that Microsoft forgot and more.

The .NET Decimal data type is included in .NET, but is often overlooked for scientific calculations. It's high precision and exact up to 28 decimal places and it's available in any .NET environment.

You might be in a situation where you just need a lot more precision than Double can provide. I used Decimal for calculating locations in space for CNC manufacturing and pick and place control. I've found the increased precision of Decimal reduces overall errors throughout the set of calculations and it also improves the odds of reversing the calculations if necessary for debugging. In that case it ends up being a kind of oversampling.

Unfortunately, a lot of the usual number functionality is not provided for .NET. For example, you can't calculate a square root or even perform exponentiation. You can cast to Double for these operations, but you can end up with a significant loss of precision.

Note All of this I've used in the "real world", but this is also a hobby. Although the library is performant, I've perferred accuracy and readability to raw performance.

Install

Install via NuGet package manager console:

PM> Install-Package DecimalMath.DecimalEx

Or of course you can clone the repository and pull in the projects directly.

Libraries

This project contains two portable libraries.

DecimalEx

Bridges the gap in .NET support.

  • Decimal versions of the following functions:
    • Sqrt
    • Pow
    • Exp
    • Log
    • Sin, Cos, Tan
    • ASin, ACos, ATan, ATan2
  • General Decimal functionality:
    • Floor / Ceiling to a given number of decimal places
    • Implementations of GCF, AGMean, and a fault-tolerant Average
    • Function to get decimal places of a number (looking at bits, NOT by converting to string)
    • Other minor helper functions
  • Functionality for working with Decimal matrices as 2D arrays and a base class for implementing an NxN matrix for use in affine transformations.

Decimal2D

Provides support for high-accuracy geometric calculations. Note: This is still a work in progress. It's been used in production, but it still needs some more grooming (was originally VB code) and unit tests.

  • Support for 2D geometric objects
    • Point, Line, and Vector
    • Circle and Arc
  • Support for geometric relationships, e.g. tangent to, intersects, etc.
  • A 2D tranformation matrix with a number of provided transforms.
  • An implementation of an abstract right triangle (i.e., the sides and angles but without a location in space).
  • Generic right triangle operations.

License

This project uses the MIT License. See the license file in the same folder as this readme.

decimalmath's People

Contributors

monty241 avatar nathanpjones avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

decimalmath's Issues

Debug writes too expensive

Awesome library, but had to remove line 120 (from DecimalExTrig.cs) so as not to log. This line caused sin functions to be so slow in complex routines that debugging them was impossible. In the end I just removed all refs to system diagnostics and included the modified extension files locally.

Debug.WriteLine("{0:000}:{1,33:+0.0000000000000000000000000000;-0.0000000000000000000000000000} ->{2,33:+0.0000000000000000000000000000;-0.0000000000000000000000000000}",
doubleIteration / 2, nextAdd, result + nextAdd);

DecimalEx.Log does not return

For small inputs, e.g. 0.000000002, DecimalEx.Log does not return or at least takes an absurd amount of time. For aforementioned value the algorithm requires ~1000000000 iterations to reach adequate precision (2 decimal places). This function should switch to a different algorithm for small values and this limitation should be mentioned in the readme and function comment.
Also: if (nextAdd == 0) break;
You never compare float/double/decimal with == or !=, especially when it is the only break condition in an infinite loop. Use Abs(x) < Tolerance instead.

Rounding suggestions

While searching for something unrelated to this repository, I stumbled on it somehow. And as I did something similar in the past (I like the clever idea to use Math.Sqrt() to speed up the Sqrt!) I couldn't resit the temptation to share my decimal rounding implementation: DecimalRound.cs

(Off-topic, I consider adding a math library to Qowaiv, we might join our efforts)

Performance improvement for Sqrt

Consider using Math.Sqrt(double) to produce an initial estimate of the square root. This improved performance 5x on my machine.

        /// <summary>
        /// Returns the square root of a given number. 
        /// </summary>
        /// <param name="s">A non-negative number.</param>
        /// <remarks> 
        /// Uses an implementation of the "Babylonian Method".
        /// See http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method 
        /// </remarks>
        public static decimal Sqrt(decimal s)
        {
            if (s < 0)
                throw new ArgumentException("Square root not defined for Decimal data type when less than zero!", "s");

            // Prevent divide-by-zero errors below. Dividing either
            // of the numbers below will yield a recurring 0 value
            // for halfS eventually converging on zero.
            if (s == 0 || s == SmallestNonZeroDec) return 0;

            var x = (decimal)Math.Sqrt((double)s);
            var halfS = s / 2m;
            var lastX = -1m;
            decimal nextX;

            while (true)
            {
                nextX = x / 2m + halfS / x;

                // The next check effectively sees if we've ran out of
                // precision for our data type.
                if (nextX == x || nextX == lastX) break;

                lastX = x;
                x = nextX;
            }

            return nextX;
        }

Would there be some hyperbolic function implementation for Decimal

Hello, nathanpjones,
Your project is great and I found it from NumSharp source codes.
MS forgot to implement so many functions in decimal class, and you have finished almost the lost ones.
I use your original DecimalMath class to support decimal operation for Math in my Shone.Math () project. I find some methods still absent, such as Sinh, Cosh, Tanh, ASinh, ACosh, ATanh.
By the way, is there a chance to get these functions done in your library to perfectly matching the Math,MathF members in .NET 5?
sinh(x)=(exp(x)-exp(-x))/2
cosh(x)=(exp(x)+exp(-x))/2
tanh(x)=sinh(x)/cosh(x)
Best wishes.

Make it compatible with .Net Core

Visual Studio 2015 says that "Decimal" is not defined and that a reference to mscorlib.dll will solve the issue but then the adding of the reference is not accepted (but of Net Core?).

In any case Decimal is defined in Net Core and could normally used so there should be some incompatibilities with this library.

Log10 returning imprecise values

For certain values, the Log10 function is returning some strange results.

Call Result Expected (same as Math.Log10)
DecimalEx.Log10(0.1m) -1.0000000000000000000000000001 -1
DecimalEx.Log10(0.01m) -1.999999999999999999999999999 -2
DecimalEx.Log10(0.001m) -2.9999999999999999999999999924 -3

Ideally, these results should be the same as the Math.Log10 function, as by definition, the Log10 of 0.1 is the integer -1.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.