diff --git a/src/stdlib/Math.fs b/src/stdlib/Math.fs index 897d8cd..07a72e0 100644 --- a/src/stdlib/Math.fs +++ b/src/stdlib/Math.fs @@ -69,6 +69,25 @@ type IExports = /// Return the integer square root of the non-negative integer n /// See https://docs.python.org/3/library/math.html#math.isqrt abstract isqrt: n: int -> int + /// Return x * (2**i) accurately + /// See https://docs.python.org/3/library/math.html#math.ldexp + abstract ldexp: x: float * i: nativeint -> float + /// Return the mantissa and exponent of x as the pair (m, e) + /// See https://docs.python.org/3/library/math.html#math.frexp + abstract frexp: x: float -> float * int + /// Return the fractional and integer parts of x + /// See https://docs.python.org/3/library/math.html#math.modf + abstract modf: x: float -> float * float + /// Return IEEE 754-style remainder of x with respect to y (Python 3.8+) + /// See https://docs.python.org/3/library/math.html#math.remainder + abstract remainder: x: float * y: float -> float + /// Return True if the values a and b are close to each other + /// See https://docs.python.org/3/library/math.html#math.isclose + abstract isclose: a: float * b: float -> bool + /// Return True if the values a and b are close to each other with custom tolerances + /// See https://docs.python.org/3/library/math.html#math.isclose + [] + abstract isclose: a: float * b: float * ?rel_tol: float * ?abs_tol: float -> bool /// Return the least common multiple of the integers /// See https://docs.python.org/3/library/math.html#math.lcm abstract lcm: [] ints: int[] -> int @@ -107,6 +126,12 @@ type IExports = /// Check if x is a NaN (not a number) /// See https://docs.python.org/3/library/math.html#math.isnan abstract isnan: x: int -> bool + /// Return the next floating-point value after x towards y (Python 3.9+) + /// See https://docs.python.org/3/library/math.html#math.nextafter + abstract nextafter: x: float * y: float -> float + /// Return the value of the least significant bit of the float x (Python 3.9+) + /// See https://docs.python.org/3/library/math.html#math.ulp + abstract ulp: x: float -> float // ======================================================================== // Power and logarithmic functions @@ -121,6 +146,9 @@ type IExports = /// Return the natural logarithm of x /// See https://docs.python.org/3/library/math.html#math.log abstract log: x: float -> float + /// Return the logarithm of x to the given base + /// See https://docs.python.org/3/library/math.html#math.log + abstract log: x: float * ``base``: float -> float /// Return the natural logarithm of 1+x (base e) /// See https://docs.python.org/3/library/math.html#math.log1p abstract log1p: x: float -> float @@ -136,6 +164,12 @@ type IExports = /// Return the square root of x /// See https://docs.python.org/3/library/math.html#math.sqrt abstract sqrt: x: float -> float + /// Return 2 raised to the power x (Python 3.11+) + /// See https://docs.python.org/3/library/math.html#math.exp2 + abstract exp2: x: float -> float + /// Return the cube root of x (Python 3.11+) + /// See https://docs.python.org/3/library/math.html#math.cbrt + abstract cbrt: x: float -> float // ======================================================================== // Trigonometric functions diff --git a/test/TestMath.fs b/test/TestMath.fs index ea0fb96..6141b45 100644 --- a/test/TestMath.fs +++ b/test/TestMath.fs @@ -224,3 +224,60 @@ let ``test gamma works`` () = [] let ``test lgamma works`` () = math.lgamma 1.0 |> equal 0.0 + +[] +let ``test log with base works`` () = + math.log (8.0, 2.0) |> equal 3.0 + math.log (100.0, 10.0) |> equal 2.0 + +[] +let ``test ldexp works`` () = + math.ldexp (1.0, 3n) |> equal 8.0 + math.ldexp (0.5, 2n) |> equal 2.0 + +[] +let ``test frexp works`` () = + let m, e = math.frexp 8.0 + m |> equal 0.5 + e |> equal 4 + +[] +let ``test modf works`` () = + let frac, intPart = math.modf 3.7 + (frac > 0.699 && frac < 0.701) |> equal true + intPart |> equal 3.0 + +[] +let ``test remainder works`` () = + math.remainder (10.0, 3.0) |> equal 1.0 + math.remainder (5.0, 2.0) |> equal 1.0 + +[] +let ``test isclose works`` () = + math.isclose (1.0, 1.0) |> equal true + math.isclose (1.0, 2.0) |> equal false + +[] +let ``test isclose with tolerances works`` () = + math.isclose (1.0, 1.001, rel_tol=0.01) |> equal true + math.isclose (1.0, 2.0, abs_tol=0.1) |> equal false + +[] +let ``test nextafter works`` () = + let x = math.nextafter (1.0, 2.0) + (x > 1.0) |> equal true + +[] +let ``test ulp works`` () = + let x = math.ulp 1.0 + (x > 0.0) |> equal true + +[] +let ``test exp2 works`` () = + math.exp2 3.0 |> equal 8.0 + math.exp2 0.0 |> equal 1.0 + +[] +let ``test cbrt works`` () = + math.isclose (math.cbrt 27.0, 3.0) |> equal true + math.isclose (math.cbrt 8.0, 2.0) |> equal true