Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ name: Fable.Python

All notable changes to this project will be documented in this file.

## Unreleased

### 🐞 Bug Fixes

* Fix `math.factorial` binding: changed signature from `float -> float` to `int -> int` to match Python 3.12+ where float arguments raise `TypeError`. Fixes test to use integer literals.

### ✨ Enhancements

* Add missing `math` module constants: `pi`, `e`, `tau`, `inf`, `nan`
* Add missing `math` module functions: `sqrt`, `degrees`, `radians`, `trunc`, `hypot`, `fsum`, `isqrt`, `prod`, `perm`, `acosh`, `asinh`, `atanh`, `cosh`, `sinh`, `tanh`, `erf`, `erfc`, `gamma`, `lgamma`
* Fix `math.dist` signature to accept float arrays (for multi-dimensional distance)

## 5.0.0-rc.3 - 2026-04-16

### 🐞 Bug Fixes
Expand Down
132 changes: 122 additions & 10 deletions src/stdlib/Math.fs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,30 @@ open Fable.Core

[<Erase>]
type IExports =
// ========================================================================
// Constants
// ========================================================================

/// The mathematical constant π = 3.141592…
/// See https://docs.python.org/3/library/math.html#math.pi
abstract pi: float
/// The mathematical constant e = 2.718281…
/// See https://docs.python.org/3/library/math.html#math.e
abstract e: float
/// The mathematical constant τ = 6.283185… (2π)
/// See https://docs.python.org/3/library/math.html#math.tau
abstract tau: float
/// Floating-point positive infinity
/// See https://docs.python.org/3/library/math.html#math.inf
abstract inf: float
/// A floating-point "not a number" (NaN) value
/// See https://docs.python.org/3/library/math.html#math.nan
abstract nan: float

// ========================================================================
// Number-theoretic and representation functions
// ========================================================================

/// Return the ceiling of x as an integer
/// See https://docs.python.org/3/library/math.html#math.ceil
abstract ceil: x: int -> int
Expand All @@ -23,22 +47,48 @@ type IExports =
/// Return the absolute value of x
/// See https://docs.python.org/3/library/math.html#math.fabs
abstract fabs: x: float -> float
/// Return the factorial of x
/// Return the factorial of n as an integer. Raises ValueError if n is negative.
/// Note: float arguments were deprecated in Python 3.9 and removed in Python 3.12.
/// See https://docs.python.org/3/library/math.html#math.factorial
abstract factorial: x: float -> float
abstract factorial: n: int -> int
/// Return the floor of x as an integer
/// See https://docs.python.org/3/library/math.html#math.floor
abstract floor: x: int -> int
/// Return the floor of x as an integer
/// See https://docs.python.org/3/library/math.html#math.floor
abstract floor: x: float -> int
/// Return the remainder of x / y
/// Return the floating-point remainder of x / y
/// See https://docs.python.org/3/library/math.html#math.fmod
abstract fmod: x: int -> y: int -> int

/// Return an accurate floating-point sum of values in the iterable
/// See https://docs.python.org/3/library/math.html#math.fsum
abstract fsum: iterable: float seq -> float
/// Return the greatest common divisor of the integers
/// See https://docs.python.org/3/library/math.html#math.gcd
abstract gcd: [<ParamArray>] ints: int[] -> int
/// 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 the least common multiple of the integers
/// See https://docs.python.org/3/library/math.html#math.lcm
abstract lcm: [<ParamArray>] ints: int[] -> int
/// Return the number of ways to choose k items from n items without repetition and with order
/// See https://docs.python.org/3/library/math.html#math.perm
abstract perm: n: int -> int
/// Return the number of ways to choose k items from n items without repetition and with order
/// See https://docs.python.org/3/library/math.html#math.perm
abstract perm: n: int * k: int -> int
/// Return the product of all elements in the iterable
/// See https://docs.python.org/3/library/math.html#math.prod
abstract prod: iterable: 'T seq -> 'T
/// Truncate x to an integer (towards zero)
/// See https://docs.python.org/3/library/math.html#math.trunc
abstract trunc: x: float -> int

// ========================================================================
// Floating-point predicates
// ========================================================================

/// Check if x is neither an infinity nor a NaN
/// See https://docs.python.org/3/library/math.html#math.isfinite
abstract isfinite: x: float -> bool
Expand All @@ -57,9 +107,10 @@ 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 least common multiple of the integers
/// See https://docs.python.org/3/library/math.html#math.lcm
abstract lcm: [<ParamArray>] ints: int[] -> int

// ========================================================================
// Power and logarithmic functions
// ========================================================================

/// Return e raised to the power of x
/// See https://docs.python.org/3/library/math.html#math.exp
Expand All @@ -82,6 +133,13 @@ type IExports =
/// Return x raised to the power y
/// See https://docs.python.org/3/library/math.html#math.pow
abstract pow: x: float -> y: float -> float
/// Return the square root of x
/// See https://docs.python.org/3/library/math.html#math.sqrt
abstract sqrt: x: float -> float

// ========================================================================
// Trigonometric functions
// ========================================================================

/// Return the arc cosine of x in radians
/// See https://docs.python.org/3/library/math.html#math.acos
Expand All @@ -98,15 +156,69 @@ type IExports =
/// Return the cosine of x radians
/// See https://docs.python.org/3/library/math.html#math.cos
abstract cos: x: float -> float
/// Return the Euclidean distance between two points
/// See https://docs.python.org/3/library/math.html#math.dist
abstract dist: p: float -> q: float -> float
/// Return the sine of x radians
/// See https://docs.python.org/3/library/math.html#math.sin
abstract sin: x: float -> float
/// Return the tangent of x radians
/// See https://docs.python.org/3/library/math.html#math.tan
abstract tan: x: float -> float
/// Return the Euclidean norm of a sequence of coordinates
/// See https://docs.python.org/3/library/math.html#math.hypot
abstract hypot: [<ParamArray>] coordinates: float[] -> float
/// Convert angle x from radians to degrees
/// See https://docs.python.org/3/library/math.html#math.degrees
abstract degrees: x: float -> float
/// Convert angle x from degrees to radians
/// See https://docs.python.org/3/library/math.html#math.radians
abstract radians: x: float -> float

// ========================================================================
// Hyperbolic functions
// ========================================================================

/// Return the inverse hyperbolic cosine of x
/// See https://docs.python.org/3/library/math.html#math.acosh
abstract acosh: x: float -> float
/// Return the inverse hyperbolic sine of x
/// See https://docs.python.org/3/library/math.html#math.asinh
abstract asinh: x: float -> float
/// Return the inverse hyperbolic tangent of x
/// See https://docs.python.org/3/library/math.html#math.atanh
abstract atanh: x: float -> float
/// Return the hyperbolic cosine of x
/// See https://docs.python.org/3/library/math.html#math.cosh
abstract cosh: x: float -> float
/// Return the hyperbolic sine of x
/// See https://docs.python.org/3/library/math.html#math.sinh
abstract sinh: x: float -> float
/// Return the hyperbolic tangent of x
/// See https://docs.python.org/3/library/math.html#math.tanh
abstract tanh: x: float -> float

// ========================================================================
// Special functions
// ========================================================================

/// Return the error function at x
/// See https://docs.python.org/3/library/math.html#math.erf
abstract erf: x: float -> float
/// Return the complementary error function at x
/// See https://docs.python.org/3/library/math.html#math.erfc
abstract erfc: x: float -> float
/// Return the Gamma function at x
/// See https://docs.python.org/3/library/math.html#math.gamma
abstract gamma: x: float -> float
/// Return the natural logarithm of the absolute value of the Gamma function at x
/// See https://docs.python.org/3/library/math.html#math.lgamma
abstract lgamma: x: float -> float

// ========================================================================
// Distance and geometry
// ========================================================================

/// Return the Euclidean distance between two points p and q
/// See https://docs.python.org/3/library/math.html#math.dist
abstract dist: p: float[] -> q: float[] -> float

/// Mathematical functions
[<ImportAll("math")>]
Expand Down
109 changes: 107 additions & 2 deletions test/TestMath.fs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ let ``test fabs works`` () =

[<Fact>]
let ``test factorial works`` () =
math.factorial 5.0 |> equal 120.0
math.factorial 0.0 |> equal 1.0
math.factorial 5 |> equal 120
math.factorial 0 |> equal 1

[<Fact>]
let ``test fmod works`` () =
Expand Down Expand Up @@ -119,3 +119,108 @@ let ``test atan works`` () =
[<Fact>]
let ``test atan2 works`` () =
math.atan2 0.0 1.0 |> equal 0.0

[<Fact>]
let ``test pi constant works`` () =
math.pi |> fun x -> (x > 3.14159 && x < 3.14160) |> equal true

[<Fact>]
let ``test e constant works`` () =
math.e |> fun x -> (x > 2.71828 && x < 2.71829) |> equal true

[<Fact>]
let ``test tau constant works`` () =
math.tau |> fun x -> (x > 6.28318 && x < 6.28319) |> equal true

[<Fact>]
let ``test inf constant works`` () =
math.isinf math.inf |> equal true

[<Fact>]
let ``test sqrt works`` () =
math.sqrt 4.0 |> equal 2.0
math.sqrt 9.0 |> equal 3.0

[<Fact>]
let ``test degrees works`` () =
math.degrees math.pi |> fun x -> (x > 179.999 && x < 180.001) |> equal true

[<Fact>]
let ``test radians works`` () =
math.radians 180.0 |> fun x -> (x > 3.14158 && x < 3.14160) |> equal true

[<Fact>]
let ``test trunc works`` () =
math.trunc 2.7 |> equal 2
math.trunc -2.7 |> equal -2

[<Fact>]
let ``test hypot works`` () =
math.hypot (3.0, 4.0) |> equal 5.0

[<Fact>]
let ``test isqrt works`` () =
math.isqrt 16 |> equal 4
math.isqrt 17 |> equal 4

[<Fact>]
let ``test fsum works`` () =
math.fsum [ 1.0; 2.0; 3.0 ] |> equal 6.0

[<Fact>]
let ``test nan constant works`` () =
math.isnan math.nan |> equal true

[<Fact>]
let ``test prod works`` () =
math.prod [ 1; 2; 3; 4 ] |> equal 24

[<Fact>]
let ``test perm works`` () =
math.perm 5 |> equal 120
math.perm (5, 2) |> equal 20

[<Fact>]
let ``test dist works`` () =
math.dist [| 0.0; 0.0 |] [| 3.0; 4.0 |] |> equal 5.0

[<Fact>]
let ``test cosh works`` () =
math.cosh 0.0 |> equal 1.0

[<Fact>]
let ``test sinh works`` () =
math.sinh 0.0 |> equal 0.0

[<Fact>]
let ``test tanh works`` () =
math.tanh 0.0 |> equal 0.0

[<Fact>]
let ``test acosh works`` () =
math.acosh 1.0 |> equal 0.0

[<Fact>]
let ``test asinh works`` () =
math.asinh 0.0 |> equal 0.0

[<Fact>]
let ``test atanh works`` () =
math.atanh 0.0 |> equal 0.0

[<Fact>]
let ``test erf works`` () =
math.erf 0.0 |> equal 0.0

[<Fact>]
let ``test erfc works`` () =
math.erfc 0.0 |> equal 1.0

[<Fact>]
let ``test gamma works`` () =
math.gamma 1.0 |> equal 1.0
math.gamma 5.0 |> equal 24.0

[<Fact>]
let ``test lgamma works`` () =
math.lgamma 1.0 |> equal 0.0
Loading