Skip to content

Add missing math functions defined by IEEE 754:2019 #20137

@dcwuser

Description

@dcwuser

These are very standard methods used in numerical computing.

namespace System
{
    public static partial class Math
    {
        // (1 + x)^n
        public static double Compound(double x, double n);

        // e^x - 1
        public static double ExpM1(double x);

        // 2^x
        public static double Exp2(double x);

        // 2^x - 1
        public static double Exp2M1(double x);

        // 10^x
        public static double Exp10(double x);

        // 10^x - 1
        public static double Exp10M1(double x);

        // sqrt(x^2 + y^2)
        public static double Hypot(double x, double y);

        // log(1 + x)
        public static double LogP1(double x);

        // log2(1 + x)
        public static double Log2P1(double x);

        // log10(1 + x)
        public static double Log10P1(double x);

        // x^(1 / n)
        public static double Root(double x, double n);

        // sin(pi * x)
        public static double SinPi(double x);

        // cos(pi * x)
        public static double CosPi(double x);

        // tan(pi * x)
        public static double TanPi(double x);

        // asin(x) / pi
        public static double AsinPi(double x);

        // acos(x) / pi
        public static double AcosPi(double x);

        // atan(x) / pi
        public static double AtanPi(double x);

        // special handling
        public static double Atan2Pi(double y, double x);
    }

    public static partial class MathF
    {
        // (1 + x)^n
        public static float Compound(float x, float n);

        // e^x - 1
        public static float ExpM1(float x);

        // 2^x
        public static float Exp2(float x);

        // 2^x - 1
        public static float Exp2M1(float x);

        // 10^x
        public static float Exp10(float x);

        // 10^x - 1
        public static float Exp10M1(float x);

        // sqrt(x^2 + y^2)
        public static float Hypot(float x, float y);

        // log(1 + x)
        public static float LogP1(float x);

        // log2(1 + x)
        public static float Log2P1(float x);

        // log10(1 + x)
        public static float Log10P1(float x);

        // x^(1 / n)
        public static float Root(float x, float n);

        // sin(pi * x)
        public static float SinPi(float x);

        // cos(pi * x)
        public static float CosPi(float x);

        // tan(pi * x)
        public static float TanPi(float x);

        // asin(x) / pi
        public static float AsinPi(float x);

        // acos(x) / pi
        public static float AcosPi(float x);

        // atan(x) / pi
        public static float AtanPi(float x);

        // special handling
        public static float Atan2Pi(float y, float x);
    }
}

They appear, with exactly these names, in the Java Math class and Boost and GSL libraries, in many other mathematical libraries, and in many articles in the numerical computing literature.

Naming: The names are somewhat cryptic. .NET coding guidelines would probably favor ExpMinusOne over Expm1, etc. On the other hand, the names are quite standardized. We would need to decide whether conforming to the expectations of advanced users or giving a better hint at meaning to less advanced users is more important.

Location: The obvious place is System.Math, but: (i) this class is already quite a jumble, (ii) it mostly follows math.h of the C standard library, which does not contain these functions, and (iii) the presence of these functions might baffle naive users. One possibility would be to add a MoreMath or AdvancedMath static class in the System.Numerics namespace, which would also be a natural place for future advanced functions such as erf, Gamma, etc.

Domain and Range: The only slightly non-trivial issue here is that Log1p is not defined for x < -1. We would need to decide whether to retutrn NaN or throw ArgumentOutOfRangeException.

Implementation and Performance: Implementations are straightforward and well-established. Each can be executed over the entire range with a handfull of flops, making them about as fast as most other standard math functions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    api-approvedAPI was approved in API review, it can be implementedarea-System.Numericshelp wanted[up-for-grabs] Good issue for external contributors

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions