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
649 changes: 603 additions & 46 deletions src/decimo/bigdecimal/bigdecimal.mojo

Large diffs are not rendered by default.

80 changes: 72 additions & 8 deletions src/decimo/bigdecimal/comparison.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -111,44 +111,108 @@ def compare(x1: BigDecimal, x2: BigDecimal) -> Int8:


def equal(x1: BigDecimal, x2: BigDecimal) -> Bool:
"""Returns whether x1 equals x2."""
"""Returns whether x1 equals x2.

Args:
x1: The first operand.
x2: The second operand.

Returns:
True if x1 equals x2, False otherwise.
"""
return compare(x1, x2) == 0


def not_equal(x1: BigDecimal, x2: BigDecimal) -> Bool:
"""Returns whether x1 does not equal x2."""
"""Returns whether x1 does not equal x2.

Args:
x1: The first operand.
x2: The second operand.

Returns:
True if x1 does not equal x2, False otherwise.
"""
return compare(x1, x2) != 0


def less(x1: BigDecimal, x2: BigDecimal) -> Bool:
"""Returns whether x1 is less than x2."""
"""Returns whether x1 is less than x2.

Args:
x1: The first operand.
x2: The second operand.

Returns:
True if x1 is less than x2, False otherwise.
"""
return compare(x1, x2) < 0


def less_equal(x1: BigDecimal, x2: BigDecimal) -> Bool:
"""Returns whether x1 is less than or equal to x2."""
"""Returns whether x1 is less than or equal to x2.

Args:
x1: The first operand.
x2: The second operand.

Returns:
True if x1 is less than or equal to x2, False otherwise.
"""
return compare(x1, x2) <= 0


def greater(x1: BigDecimal, x2: BigDecimal) -> Bool:
"""Returns whether x1 is greater than x2."""
"""Returns whether x1 is greater than x2.

Args:
x1: The first operand.
x2: The second operand.

Returns:
True if x1 is greater than x2, False otherwise.
"""
return compare(x1, x2) > 0


def greater_equal(x1: BigDecimal, x2: BigDecimal) -> Bool:
"""Returns whether x1 is greater than or equal to x2."""
"""Returns whether x1 is greater than or equal to x2.

Args:
x1: The first operand.
x2: The second operand.

Returns:
True if x1 is greater than or equal to x2, False otherwise.
"""
return compare(x1, x2) >= 0


def max(x1: BigDecimal, x2: BigDecimal) -> BigDecimal:
"""Returns the maximum of x1 and x2."""
"""Returns the maximum of x1 and x2.

Args:
x1: The first operand.
x2: The second operand.

Returns:
The larger of the two values.
"""
if compare(x1, x2) >= 0:
return x1.copy()
return x2.copy()


def min(x1: BigDecimal, x2: BigDecimal) -> BigDecimal:
"""Returns the minimum of x1 and x2."""
"""Returns the minimum of x1 and x2.

Args:
x1: The first operand.
x2: The second operand.

Returns:
The smaller of the two values.
"""
if compare(x1, x2) <= 0:
return x1.copy()
return x2.copy()
52 changes: 48 additions & 4 deletions src/decimo/bigdecimal/constants.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,14 @@ comptime PI_1024 = BigDecimal(
# we check whether the precision is higher than the current precision.
# If yes, then we save it into the global scope as cached value.
def pi(precision: Int) raises -> BigDecimal:
"""Calculates π using the fastest available algorithm."""
"""Calculates π using the fastest available algorithm.

Args:
precision: The number of significant digits to compute.

Returns:
The value of π to the specified precision.
"""

if precision < 0:
raise Error("Precision must be non-negative")
Expand All @@ -179,9 +186,17 @@ struct Rational:
"""Represents a rational number p/q for exact arithmetic."""

var p: BigInt10 # numerator
"""The numerator of the rational number."""
var q: BigInt10 # denominator
"""The denominator of the rational number."""

def __init__(out self, p: BigInt10, q: BigInt10):
"""Initializes a rational number from a numerator and denominator.

Args:
p: The numerator.
q: The denominator.
"""
self.p = p.copy()
self.q = q.copy()

Expand All @@ -197,6 +212,12 @@ def pi_chudnovsky_binary_split(precision: Int) raises -> BigDecimal:
(1) M(k) = (6k)! / ((3k)! * (k!)³)
(2) L(k) = 545140134*k + 13591409
(3) X(k) = (-262537412640768000)^k

Args:
precision: The number of significant digits to compute.

Returns:
The value of π to the specified precision.
"""

var working_precision = precision + 9 # 1 words
Expand Down Expand Up @@ -228,7 +249,16 @@ def pi_chudnovsky_binary_split(precision: Int) raises -> BigDecimal:


def chudnovsky_split(a: Int, b: Int, precision: Int) raises -> Rational:
"""Conducts binary splitting for Chudnovsky series from term a to b-1."""
"""Conducts binary splitting for Chudnovsky series from term a to b-1.

Args:
a: The start index of the splitting range (inclusive).
b: The end index of the splitting range (exclusive).
precision: The working precision for intermediate calculations.

Returns:
A `Rational` representing the partial sum of the Chudnovsky series.
"""

var bint_1 = BigInt10(1)
var bint_13591409 = BigInt10(13591409)
Expand Down Expand Up @@ -273,7 +303,14 @@ def chudnovsky_split(a: Int, b: Int, precision: Int) raises -> Rational:


def compute_m_k_rational(k: Int) raises -> Rational:
"""Computes M(k) = (6k)! / ((3k)! * (k!)³) as exact rational."""
"""Computes M(k) = (6k)! / ((3k)! * (k!)³) as exact rational.

Args:
k: The term index in the Chudnovsky series.

Returns:
A `Rational` with numerator (6k)!/(3k)! and denominator (k!)³.
"""

var bint_1 = BigInt10(1)

Expand All @@ -296,7 +333,14 @@ def compute_m_k_rational(k: Int) raises -> Rational:


def pi_machin(precision: Int) raises -> BigDecimal:
"""Fallback π calculation using Machin's formula."""
"""Fallback π calculation using Machin's formula.

Args:
precision: The number of significant digits to compute.

Returns:
The value of π to the specified precision.
"""

var working_precision = precision + 9

Expand Down
3 changes: 3 additions & 0 deletions src/decimo/bigdecimal/rounding.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ def round(
round(123.456, -2) -> 1E+2
round(123.456, -3) -> 0E+3
round(678.890, -3) -> 1E+3
Returns:
A new `BigDecimal` rounded to the specified number of decimal places.
"""

var ndigits_to_remove = number.scale - ndigits
Expand Down
7 changes: 7 additions & 0 deletions src/decimo/bigdecimal/trigonometric.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,13 @@ def arctan(x: BigDecimal, precision: Int) raises -> BigDecimal:
y = arctan(x),
where x can be all real numbers,
and y is in the range (-π/2, π/2).

Args:
x: The input number to compute the arctangent of.
precision: The number of significant digits for the result.

Returns:
The arctangent of x in radians, in the range (-π/2, π/2).
"""

comptime BUFFER_DIGITS = 9 # word-length, easy to append and trim
Expand Down
Loading
Loading