From 708094bdec6e6b245e196e488e1e9869c00a7b7d Mon Sep 17 00:00:00 2001 From: ZHU Yuhao Date: Wed, 8 Apr 2026 22:51:34 +0200 Subject: [PATCH 1/2] Add docstring to all functions that miss it. Fix mojo doc warnings. --- src/decimo/bigdecimal/bigdecimal.mojo | 645 +++++++++++++++++++++-- src/decimo/bigdecimal/comparison.mojo | 80 ++- src/decimo/bigdecimal/constants.mojo | 52 +- src/decimo/bigdecimal/rounding.mojo | 3 + src/decimo/bigdecimal/trigonometric.mojo | 7 + src/decimo/bigfloat/bigfloat.mojo | 224 ++++++-- src/decimo/bigint/arithmetics.mojo | 5 +- src/decimo/bigint/bigint.mojo | 563 ++++++++++++++++++-- src/decimo/bigint/bitwise.mojo | 60 ++- src/decimo/bigint10/bigint10.mojo | 385 +++++++++++++- src/decimo/biguint/arithmetics.mojo | 96 +++- src/decimo/biguint/biguint.mojo | 443 +++++++++++++++- src/decimo/biguint/exponential.mojo | 6 + src/decimo/decimal128/constants.mojo | 444 +++++++++++++--- src/decimo/decimal128/decimal128.mojo | 497 ++++++++++++++++- src/decimo/decimal128/utility.mojo | 9 + src/decimo/errors.mojo | 25 +- src/decimo/rounding_mode.mojo | 78 ++- src/decimo/str.mojo | 22 +- src/decimo/tests.mojo | 85 ++- src/decimo/toml/parser.mojo | 227 +++++++- src/decimo/toml/tokenizer.mojo | 188 ++++++- 22 files changed, 3803 insertions(+), 341 deletions(-) diff --git a/src/decimo/bigdecimal/bigdecimal.mojo b/src/decimo/bigdecimal/bigdecimal.mojo index 9213be85..9e75314e 100644 --- a/src/decimo/bigdecimal/bigdecimal.mojo +++ b/src/decimo/bigdecimal/bigdecimal.mojo @@ -107,26 +107,44 @@ struct BigDecimal( @implicit def __init__(out self, coefficient: BigUInt): - """Constructs a BigDecimal from a BigUInt object.""" + """Constructs a BigDecimal from a BigUInt object. + + Args: + coefficient: The unsigned integer coefficient. + """ self.coefficient = coefficient.copy() self.scale = 0 self.sign = False def __init__(out self, coefficient: BigUInt, scale: Int, sign: Bool): - """Constructs a BigDecimal from its components.""" + """Constructs a BigDecimal from its components. + + Args: + coefficient: The unsigned integer coefficient. + scale: The number of decimal places (power of 10 divisor). + sign: Whether the value is negative. + """ self.coefficient = coefficient.copy() self.scale = scale self.sign = sign @implicit def __init__(out self, value: BigInt10): - """Constructs a BigDecimal from a big integer.""" + """Constructs a BigDecimal from a big integer. + + Args: + value: The `BigInt10` to convert. + """ self.coefficient = value.magnitude.copy() self.scale = 0 self.sign = value.sign def __init__(out self, value: String) raises: - """Constructs a BigDecimal from a string representation.""" + """Constructs a BigDecimal from a string representation. + + Args: + value: The string to parse (e.g. "123.456" or "1.23E+5"). + """ # The string is normalized with `deciomojo.str.parse_numeric_string()`. self = Self.from_string(value) @@ -134,6 +152,9 @@ struct BigDecimal( def __init__(out self, value: Int): """Constructs a BigDecimal from an `Int` object. See `from_int()` for more information. + + Args: + value: The integer to convert. """ self = Self.from_int(value) @@ -141,6 +162,9 @@ struct BigDecimal( def __init__(out self, value: UInt): """Constructs a BigDecimal from an `UInt` object. See `from_uint()` for more information. + + Args: + value: The unsigned integer to convert. """ self = Self.from_uint(value) @@ -151,6 +175,12 @@ struct BigDecimal( Constraints: The dtype of the scalar must be integral. + + Parameters: + dtype: The data type of the scalar. + + Args: + value: The integral scalar to convert. """ comptime assert dtype.is_integral(), ( "\n***********************************************************\n" @@ -166,7 +196,11 @@ struct BigDecimal( self = Self.from_integral_scalar(value) def __init__(out self, *, py: PythonObject) raises: - """Constructs a BigDecimal from a Python Decimal object.""" + """Constructs a BigDecimal from a Python Decimal object. + + Args: + py: A Python `decimal.Decimal` object. + """ self = Self.from_python_decimal(py) # ===------------------------------------------------------------------=== # @@ -206,12 +240,27 @@ struct BigDecimal( ) -> Self: """**UNSAFE** Creates a BigDecimal from its raw components. The raw components are a single word, scale, and sign. + + Args: + word: The single raw UInt32 word for the coefficient. + scale: The number of decimal places. + sign: Whether the value is negative. + + Returns: + A `BigDecimal` constructed from the raw components. """ return Self(BigUInt(raw_words=[word]), scale, sign) @staticmethod def from_int(value: Int) -> Self: - """Creates a BigDecimal from an integer.""" + """Creates a BigDecimal from an integer. + + Args: + value: The integer to convert. + + Returns: + A `BigDecimal` representing the given integer. + """ if value == 0: return Self(coefficient=BigUInt.zero(), scale=0, sign=False) @@ -246,7 +295,14 @@ struct BigDecimal( # TODO: This method is no longer needed as UInt is now an alias for SIMD. @staticmethod def from_uint(value: UInt) -> Self: - """Creates a BigDecimal from an unsigned integer.""" + """Creates a BigDecimal from an unsigned integer. + + Args: + value: The unsigned integer to convert. + + Returns: + A `BigDecimal` representing the given unsigned integer. + """ return Self( coefficient=BigUInt.from_unsigned_integral_scalar(value), scale=0, @@ -263,6 +319,9 @@ struct BigDecimal( Returns: The BigDecimal representation of the Scalar value. + + Parameters: + dtype: The data type of the scalar. """ comptime assert dtype.is_integral(), "dtype must be integral." @@ -290,6 +349,9 @@ struct BigDecimal( If the value is a floating-point number, it is converted to a string with full precision before converting to BigDecimal. + + Parameters: + dtype: The data type of the scalar. """ comptime assert ( @@ -491,11 +553,19 @@ struct BigDecimal( # ===------------------------------------------------------------------=== # def __int__(self) raises -> Int: - """Converts the BigDecimal to an integer.""" + """Converts the BigDecimal to an integer. + + Returns: + The integer representation, truncating any fractional part. + """ return Int(self.to_string()) def __float__(self) raises -> Float64: - """Converts the BigDecimal to a floating-point number.""" + """Converts the BigDecimal to a floating-point number. + + Returns: + The `Float64` representation of this value. + """ return Float64(self.to_string()) # ===------------------------------------------------------------------=== # @@ -700,11 +770,24 @@ struct BigDecimal( def write_to[W: Writer](self, mut writer: W): """Writes the BigDecimal to a writer. This implement the `write` method of the `Writer` trait. + + Parameters: + W: A type conforming to the `Writer` interface. + + Args: + writer:: The writer instance. """ writer.write(self.to_string()) def write_repr_to[W: Writer](self, mut writer: W): - """Writes the debug representation to a writer.""" + """Writes the debug representation to a writer. + + Parameters: + W: A type conforming to the `Writer` interface. + + Args: + writer:: The writer instance. + """ writer.write('BigDecimal("', self.to_string(), '")') def to_scientific_string(self) -> String: @@ -718,6 +801,9 @@ struct BigDecimal( BigDecimal("123456.789").to_scientific_string() # "1.23456789E+5" BigDecimal("0.00123").to_scientific_string() # "1.23E-3" ``` + + Returns: + The number formatted in scientific notation. """ return self.to_string(scientific=True) @@ -733,6 +819,9 @@ struct BigDecimal( BigDecimal("123456.789").to_eng_string() # "123.456789E+3" BigDecimal("0.00123").to_eng_string() # "1.23E-3" ``` + + Returns: + The number formatted in engineering notation. """ return self.to_string(engineering=True) @@ -753,6 +842,9 @@ struct BigDecimal( BigDecimal("-9876543210.123456").to_string_with_separators() # "-9_876_543_210.123_456" ``` + + Returns: + The number formatted with digit-group separators. """ return self.to_string(delimiter=separator) @@ -765,6 +857,9 @@ struct BigDecimal( def __abs__(self) -> Self: """Returns the absolute value of this number. See `absolute()` for more information. + + Returns: + The absolute value. """ return Self( coefficient=self.coefficient, @@ -776,6 +871,9 @@ struct BigDecimal( def __neg__(self) -> Self: """Returns the negation of this number. See `negative()` for more information. + + Returns: + The negated value. """ return Self( coefficient=self.coefficient, @@ -788,6 +886,9 @@ struct BigDecimal( """Returns True if the number is nonzero. This enables `if x:` syntax, consistent with Python's `decimal.Decimal`. + + Returns: + True if the number is nonzero, False otherwise. """ return not self.coefficient.is_zero() @@ -797,6 +898,9 @@ struct BigDecimal( This enables `+x` syntax, consistent with Python's `decimal.Decimal`. In Python, unary plus applies context rounding. Here it returns a copy. + + Returns: + A copy of this number. """ return self.copy() @@ -808,18 +912,50 @@ struct BigDecimal( @always_inline def __add__(self, other: Self) raises -> Self: + """Adds two values. + + Args: + other: The right-hand side operand. + + Returns: + The sum of the two values. + """ return decimo.bigdecimal.arithmetics.add(self, other) @always_inline def __sub__(self, other: Self) raises -> Self: + """Subtracts two values. + + Args: + other: The right-hand side operand. + + Returns: + The difference of the two values. + """ return decimo.bigdecimal.arithmetics.subtract(self, other) @always_inline def __mul__(self, other: Self) -> Self: + """Multiplies two values. + + Args: + other: The right-hand side operand. + + Returns: + The product of the two values. + """ return decimo.bigdecimal.arithmetics.multiply(self, other) @always_inline def __truediv__(self, other: Self) raises -> Self: + """Divides two values using true division. + + Args: + other: The right-hand side operand. + + Returns: + The quotient of the two values. + """ return decimo.bigdecimal.arithmetics.true_divide( self, other, precision=PRECISION ) @@ -828,6 +964,12 @@ struct BigDecimal( def __floordiv__(self, other: Self) raises -> Self: """Returns the result of floor division. See `arithmetics.truncate_divide()` for more information. + + Args: + other: The right-hand side operand. + + Returns: + The integer quotient, truncated toward zero. """ return decimo.bigdecimal.arithmetics.truncate_divide(self, other) @@ -835,6 +977,12 @@ struct BigDecimal( def __mod__(self, other: Self) raises -> Self: """Returns the result of modulo operation. See `arithmetics.truncate_modulo()` for more information. + + Args: + other: The right-hand side operand. + + Returns: + The remainder after truncated division. """ return decimo.bigdecimal.arithmetics.truncate_modulo( self, other, precision=PRECISION @@ -842,7 +990,14 @@ struct BigDecimal( @always_inline def __pow__(self, exponent: Self) raises -> Self: - """Returns the result of exponentiation.""" + """Returns the result of exponentiation. + + Args: + exponent: The power to raise this value to. + + Returns: + This value raised to the given exponent. + """ return decimo.bigdecimal.exponential.power( self, exponent, precision=PRECISION ) @@ -857,6 +1012,12 @@ struct BigDecimal( Uses truncated division (toward zero), matching Python's `decimal.Decimal.__divmod__()` behavior. + + Args: + other: The right-hand side operand. + + Returns: + A tuple of `(quotient, remainder)` from truncated division. """ var quotient = decimo.bigdecimal.arithmetics.truncate_divide( self, other @@ -868,7 +1029,14 @@ struct BigDecimal( return (quotient^, remainder^) def __rdivmod__(self, other: Self) raises -> Tuple[Self, Self]: - """Returns `divmod(other, self)` for right-side divmod.""" + """Returns `divmod(other, self)` for right-side divmod. + + Args: + other: The left-hand side operand. + + Returns: + A tuple of `(quotient, remainder)` from truncated division. + """ var quotient = decimo.bigdecimal.arithmetics.truncate_divide( other, self ) @@ -886,34 +1054,90 @@ struct BigDecimal( @always_inline def __radd__(self, other: Self) raises -> Self: + """Adds two values (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The sum of the two values. + """ return decimo.bigdecimal.arithmetics.add(self, other) @always_inline def __rsub__(self, other: Self) raises -> Self: + """Subtracts two values (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The difference `other - self`. + """ return decimo.bigdecimal.arithmetics.subtract(other, self) @always_inline def __rmul__(self, other: Self) raises -> Self: + """Multiplies two values (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The product of the two values. + """ return decimo.bigdecimal.arithmetics.multiply(self, other) @always_inline def __rfloordiv__(self, other: Self) raises -> Self: + """Divides two values using floor division (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The integer quotient `other // self`, truncated toward zero. + """ return decimo.bigdecimal.arithmetics.truncate_divide(other, self) @always_inline def __rmod__(self, other: Self) raises -> Self: + """Returns the remainder of division (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The remainder `other % self`. + """ return decimo.bigdecimal.arithmetics.truncate_modulo( other, self, precision=PRECISION ) @always_inline def __rpow__(self, base: Self) raises -> Self: + """Raises to a power (reflected). + + Args: + base: The base to raise to the power of self. + + Returns: + The base raised to the power of self. + """ return decimo.bigdecimal.exponential.power( base, self, precision=PRECISION ) @always_inline def __rtruediv__(self, other: Self) raises -> Self: + """Divides two values using true division (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The quotient `other / self`. + """ return decimo.bigdecimal.arithmetics.true_divide( other, self, precision=PRECISION ) @@ -927,28 +1151,58 @@ struct BigDecimal( @always_inline def __iadd__(mut self, other: Self) raises: + """Adds in place. + + Args: + other: The right-hand side operand. + """ decimo.bigdecimal.arithmetics.add_inplace(self, other) @always_inline def __isub__(mut self, other: Self) raises: + """Subtracts in place. + + Args: + other: The right-hand side operand. + """ decimo.bigdecimal.arithmetics.subtract_inplace(self, other) @always_inline def __imul__(mut self, other: Self) raises: + """Multiplies in place. + + Args: + other: The right-hand side operand. + """ decimo.bigdecimal.arithmetics.multiply_inplace(self, other) @always_inline def __itruediv__(mut self, other: Self) raises: + """Divides in place using true division. + + Args: + other: The right-hand side operand. + """ self = decimo.bigdecimal.arithmetics.true_divide( self, other, precision=PRECISION ) @always_inline def __ifloordiv__(mut self, other: Self) raises: + """Divides in place using floor division. + + Args: + other: The right-hand side operand. + """ self = decimo.bigdecimal.arithmetics.truncate_divide(self, other) @always_inline def __imod__(mut self, other: Self) raises: + """Computes the remainder in place. + + Args: + other: The right-hand side operand. + """ self = decimo.bigdecimal.arithmetics.truncate_modulo( self, other, precision=PRECISION ) @@ -960,32 +1214,74 @@ struct BigDecimal( @always_inline def __gt__(self, other: Self) -> Bool: - """Returns whether self is greater than other.""" + """Returns whether self is greater than other. + + Args: + other: The value to compare against. + + Returns: + True if self is greater than other, False otherwise. + """ return decimo.bigdecimal.comparison.compare(self, other) > 0 @always_inline def __ge__(self, other: Self) -> Bool: - """Returns whether self is greater than or equal to other.""" + """Returns whether self is greater than or equal to other. + + Args: + other: The value to compare against. + + Returns: + True if self is greater than or equal to other, False otherwise. + """ return decimo.bigdecimal.comparison.compare(self, other) >= 0 @always_inline def __lt__(self, other: Self) -> Bool: - """Returns whether self is less than other.""" + """Returns whether self is less than other. + + Args: + other: The value to compare against. + + Returns: + True if self is less than other, False otherwise. + """ return decimo.bigdecimal.comparison.compare(self, other) < 0 @always_inline def __le__(self, other: Self) -> Bool: - """Returns whether self is less than or equal to other.""" + """Returns whether self is less than or equal to other. + + Args: + other: The value to compare against. + + Returns: + True if self is less than or equal to other, False otherwise. + """ return decimo.bigdecimal.comparison.compare(self, other) <= 0 @always_inline def __eq__(self, other: Self) -> Bool: - """Returns whether self equals other.""" + """Returns whether self equals other. + + Args: + other: The value to compare against. + + Returns: + True if the two values are equal, False otherwise. + """ return decimo.bigdecimal.comparison.compare(self, other) == 0 @always_inline def __ne__(self, other: Self) -> Bool: - """Returns whether self does not equal other.""" + """Returns whether self does not equal other. + + Args: + other: The value to compare against. + + Returns: + True if the two values are not equal, False otherwise. + """ return decimo.bigdecimal.comparison.compare(self, other) != 0 # ===------------------------------------------------------------------=== # @@ -997,6 +1293,12 @@ struct BigDecimal( """Rounds the number to the specified number of decimal places. If `ndigits` is not given, rounds to 0 decimal places. If rounding causes errors, returns the value itself. + + Args: + ndigits: The number of decimal places to round to. + + Returns: + A new `BigDecimal` rounded to the specified decimal places. """ try: return decimo.bigdecimal.rounding.round( @@ -1011,6 +1313,9 @@ struct BigDecimal( """Rounds the number to the specified number of decimal places. If `ndigits` is not given, rounds to 0 decimal places. If rounding causes errors, returns the value itself. + + Returns: + A new `BigDecimal` rounded to 0 decimal places. """ try: return decimo.bigdecimal.rounding.round( @@ -1028,6 +1333,9 @@ struct BigDecimal( Equivalent to `math.ceil()` in Python. Returns a BigDecimal with scale 0. + + Returns: + The ceiling of this value. """ if self.scale <= 0: return self.copy() @@ -1045,6 +1353,9 @@ struct BigDecimal( Equivalent to `math.floor()` in Python. Returns a BigDecimal with scale 0. + + Returns: + The floor of this value. """ if self.scale <= 0: return self.copy() @@ -1062,6 +1373,9 @@ struct BigDecimal( Equivalent to `math.trunc()` in Python. Returns a BigDecimal with scale 0. + + Returns: + The truncated integer part of this value. """ if self.scale <= 0: return self.copy() @@ -1079,6 +1393,12 @@ struct BigDecimal( def compare(self, other: Self) raises -> Int8: """Compares two BigDecimal numbers. See `comparison.compare()` for more information. + + Args: + other: The value to compare against. + + Returns: + 1 if self > other, 0 if equal, -1 if self < other. """ return decimo.bigdecimal.comparison.compare(self, other) @@ -1086,6 +1406,12 @@ struct BigDecimal( def compare_absolute(self, other: Self) raises -> Int8: """Compares two BigDecimal numbers by absolute value. See `comparison.compare_absolute()` for more information. + + Args: + other: The value to compare against. + + Returns: + 1 if |self| > |other|, 0 if equal, -1 if |self| < |other|. """ return decimo.bigdecimal.comparison.compare_absolute(self, other) @@ -1093,12 +1419,26 @@ struct BigDecimal( @always_inline def max(self, other: Self) raises -> Self: - """Returns the maximum of two BigDecimal numbers.""" + """Returns the maximum of two BigDecimal numbers. + + Args: + other: The value to compare against. + + Returns: + The larger of the two values. + """ return decimo.bigdecimal.comparison.max(self, other) @always_inline def min(self, other: Self) raises -> Self: - """Returns the minimum of two BigDecimal numbers.""" + """Returns the minimum of two BigDecimal numbers. + + Args: + other: The value to compare against. + + Returns: + The smaller of the two values. + """ return decimo.bigdecimal.comparison.min(self, other) # === Constants === # @@ -1106,13 +1446,27 @@ struct BigDecimal( @always_inline @staticmethod def pi(precision: Int) raises -> Self: - """Returns the mathematical constant pi to the specified precision.""" + """Returns the mathematical constant pi to the specified precision. + + Args: + precision: The number of significant digits to compute. + + Returns: + The value of π to the specified precision. + """ return decimo.bigdecimal.constants.pi(precision=precision) @always_inline @staticmethod def e(precision: Int) raises -> Self: - """Returns the mathematical constant e to the specified precision.""" + """Returns the mathematical constant e to the specified precision. + + Args: + precision: The number of significant digits to compute. + + Returns: + The value of e to the specified precision. + """ return decimo.bigdecimal.exponential.exp( x=Self(BigUInt.one()), precision=precision ) @@ -1121,12 +1475,26 @@ struct BigDecimal( @always_inline def exp(self, precision: Int = PRECISION) raises -> Self: - """Returns the exponential of the BigDecimal number.""" + """Returns the exponential of the BigDecimal number. + + Args: + precision: The number of significant digits for the result. + + Returns: + The value of e raised to the power of self. + """ return decimo.bigdecimal.exponential.exp(self, precision) @always_inline def ln(self, precision: Int = PRECISION) raises -> Self: - """Returns the natural logarithm of the BigDecimal number.""" + """Returns the natural logarithm of the BigDecimal number. + + Args: + precision: The number of significant digits for the result. + + Returns: + The natural logarithm (base e) of this value. + """ return decimo.bigdecimal.exponential.ln(self, precision) @always_inline @@ -1135,76 +1503,176 @@ struct BigDecimal( precision: Int, mut cache: decimo.bigdecimal.exponential.MathCache, ) raises -> Self: - """Returns the natural logarithm using a cache for ln(2)/ln(1.25).""" + """Returns the natural logarithm using a cache for ln(2)/ln(1.25). + + Args: + precision: The number of significant digits for the result. + cache:: The shared math constant cache for ln(2) and ln(1.25). + + Returns: + The natural logarithm (base e) of this value. + """ return decimo.bigdecimal.exponential.ln(self, precision, cache) @always_inline def log(self, base: Self, precision: Int = PRECISION) raises -> Self: """Returns the logarithm of the BigDecimal number with the given base. + + Args: + base: The logarithmic base. + precision: The number of significant digits for the result. + + Returns: + The logarithm of this value in the given base. """ return decimo.bigdecimal.exponential.log(self, base, precision) @always_inline def log10(self, precision: Int = PRECISION) raises -> Self: - """Returns the base-10 logarithm of the BigDecimal number.""" + """Returns the base-10 logarithm of the BigDecimal number. + + Args: + precision: The number of significant digits for the result. + + Returns: + The base-10 logarithm of this value. + """ return decimo.bigdecimal.exponential.log10(self, precision) @always_inline def root(self, root: Self, precision: Int = PRECISION) raises -> Self: - """Returns the root of the BigDecimal number.""" + """Returns the root of the BigDecimal number. + + Args: + root: The degree of the root (e.g. 2 for square root, 3 for cube root). + precision: The number of significant digits for the result. + + Returns: + The nth root of this value. + """ return decimo.bigdecimal.exponential.root(self, root, precision) @always_inline def sqrt(self, precision: Int = PRECISION) raises -> Self: - """Returns the square root of the BigDecimal number.""" + """Returns the square root of the BigDecimal number. + + Args: + precision: The number of significant digits for the result. + + Returns: + The square root of this value. + """ return decimo.bigdecimal.exponential.sqrt(self, precision) @always_inline def cbrt(self, precision: Int = PRECISION) raises -> Self: - """Returns the cube root of the BigDecimal number.""" + """Returns the cube root of the BigDecimal number. + + Args: + precision: The number of significant digits for the result. + + Returns: + The cube root of this value. + """ return decimo.bigdecimal.exponential.cbrt(self, precision) @always_inline def power(self, exponent: Self, precision: Int = PRECISION) raises -> Self: """Returns the result of exponentiation with the given precision. See `exponential.power()` for more information. + + Args: + exponent: The power to raise this value to. + precision: The number of significant digits for the result. + + Returns: + This value raised to the given exponent. """ return decimo.bigdecimal.exponential.power(self, exponent, precision) # === Trigonometric operations === # @always_inline def sin(self, precision: Int = PRECISION) raises -> Self: - """Returns the sine of the BigDecimal number.""" + """Returns the sine of the BigDecimal number. + + Args: + precision: The number of significant digits for the result. + + Returns: + The sine of this value. + """ return decimo.bigdecimal.trigonometric.sin(self, precision) @always_inline def cos(self, precision: Int = PRECISION) raises -> Self: - """Returns the cosine of the BigDecimal number.""" + """Returns the cosine of the BigDecimal number. + + Args: + precision: The number of significant digits for the result. + + Returns: + The cosine of this value. + """ return decimo.bigdecimal.trigonometric.cos(self, precision) @always_inline def tan(self, precision: Int = PRECISION) raises -> Self: - """Returns the tangent of the BigDecimal number.""" + """Returns the tangent of the BigDecimal number. + + Args: + precision: The number of significant digits for the result. + + Returns: + The tangent of this value. + """ return decimo.bigdecimal.trigonometric.tan(self, precision) @always_inline def cot(self, precision: Int = PRECISION) raises -> Self: - """Returns the cotangent of the BigDecimal number.""" + """Returns the cotangent of the BigDecimal number. + + Args: + precision: The number of significant digits for the result. + + Returns: + The cotangent of this value. + """ return decimo.bigdecimal.trigonometric.cot(self, precision) @always_inline def csc(self, precision: Int = PRECISION) raises -> Self: - """Returns the cosecant of the BigDecimal number.""" + """Returns the cosecant of the BigDecimal number. + + Args: + precision: The number of significant digits for the result. + + Returns: + The cosecant of this value. + """ return decimo.bigdecimal.trigonometric.csc(self, precision) @always_inline def sec(self, precision: Int = PRECISION) raises -> Self: - """Returns the secant of the BigDecimal number.""" + """Returns the secant of the BigDecimal number. + + Args: + precision: The number of significant digits for the result. + + Returns: + The secant of this value. + """ return decimo.bigdecimal.trigonometric.sec(self, precision) @always_inline def arctan(self, precision: Int = PRECISION) raises -> Self: - """Returns the arctangent of the BigDecimal number.""" + """Returns the arctangent of the BigDecimal number. + + Args: + precision: The number of significant digits for the result. + + Returns: + The arctangent of this value in radians. + """ return decimo.bigdecimal.trigonometric.arctan(self, precision) # === Arithmetic operations === # @@ -1215,6 +1683,13 @@ struct BigDecimal( ) raises -> Self: """Returns the result of true division of two BigDecimal numbers. See `arithmetics.true_divide()` for more information. + + Args: + other: The divisor. + precision: The number of significant digits for the result. + + Returns: + The quotient of the division. """ return decimo.bigdecimal.arithmetics.true_divide(self, other, precision) @@ -1224,6 +1699,13 @@ struct BigDecimal( ) raises -> Self: """Returns the result of true division with inexact precision. See `arithmetics.true_divide_inexact()` for more information. + + Args: + other: The divisor. + number_of_significant_digits: The number of significant digits for the result. + + Returns: + The quotient of the division with the specified significant digits. """ return decimo.bigdecimal.arithmetics.true_divide_inexact( self, other, number_of_significant_digits @@ -1235,6 +1717,13 @@ struct BigDecimal( ) raises -> Self: """Returns the result of division by a small UInt32 integer. See `arithmetics.true_divide_inexact_by_uint32()` for more information. + + Args: + y: The small unsigned integer divisor. + number_of_significant_digits: The number of significant digits for the result. + + Returns: + The quotient of dividing this value by the given `UInt32`. """ return decimo.bigdecimal.arithmetics.true_divide_inexact_by_uint32( self, y, number_of_significant_digits @@ -1244,6 +1733,12 @@ struct BigDecimal( def truncate_divide(self, other: Self) raises -> Self: """Returns the result of truncating division of two BigDecimal numbers. See `arithmetics.truncate_divide()` for more information. + + Args: + other: The divisor. + + Returns: + The integer quotient, truncated toward zero. """ return decimo.bigdecimal.arithmetics.truncate_divide(self, other) @@ -1274,6 +1769,9 @@ struct BigDecimal( 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 decimal places. """ return decimo.bigdecimal.rounding.round(self, ndigits, rounding_mode) @@ -1294,6 +1792,12 @@ struct BigDecimal( specific number of decimal places, use `round()` instead. See `rounding.round_to_precision()` for more information. + + Args: + precision: The number of significant digits to round to. + rounding_mode: The rounding strategy to use. + remove_extra_digit_due_to_rounding: Whether to remove an extra leading digit caused by rounding up. + fill_zeros_to_precision: Whether to pad with trailing zeros to reach the target precision. """ decimo.bigdecimal.rounding.round_to_precision( self, @@ -1405,6 +1909,9 @@ struct BigDecimal( BigDecimal("1").adjusted() # 0 (1E0) BigDecimal("0.00").adjusted() # 0 (zero has no order of magnitude) ``` + + Returns: + The adjusted exponent of this number. """ if self.coefficient.is_zero(): return 0 @@ -1463,6 +1970,9 @@ struct BigDecimal( Equivalent to `abs(self)`. Matches Python's `decimal.Decimal.copy_abs()`. + + Returns: + A copy of this number with positive sign. """ return self.__abs__() @@ -1472,6 +1982,9 @@ struct BigDecimal( Equivalent to `-self`. Matches Python's `decimal.Decimal.copy_negate()`. + + Returns: + A copy of this number with the opposite sign. """ return self.__neg__() @@ -1483,6 +1996,9 @@ struct BigDecimal( Args: other: The BigDecimal whose sign to copy. + + Returns: + A copy of this number with the sign taken from `other`. """ return Self( coefficient=self.coefficient, @@ -1508,6 +2024,9 @@ struct BigDecimal( BigDecimal("1.2").same_quantum(BigDecimal("4.56")) # False (scale 1 vs 2) BigDecimal("100").same_quantum(BigDecimal("1")) # True (both scale=0) ``` + + Returns: + True if both values have the same scale, False otherwise. """ return self.scale == other.scale @@ -1622,7 +2141,11 @@ struct BigDecimal( self.scale += precision_diff def internal_representation(self) -> String: - """Returns the internal representation of the BigDecimal as a String.""" + """Returns the internal representation of the BigDecimal as a String. + + Returns: + A formatted string showing the coefficient, scale, sign, and words. + """ # Collect all labels to find max width var fixed_labels = List[String]() fixed_labels.append("number:") @@ -1717,7 +2240,11 @@ struct BigDecimal( ) def is_integer(self) -> Bool: - """Returns True if this number represents an integer value.""" + """Returns True if this number represents an integer value. + + Returns: + True if there is no fractional part, False otherwise. + """ var number_of_trailing_zeros = self.number_of_trailing_zeros() if number_of_trailing_zeros >= self.scale: return True @@ -1726,16 +2253,28 @@ struct BigDecimal( @always_inline def is_negative(self) -> Bool: - """Returns True if this number represents a negative value.""" + """Returns True if this number represents a negative value. + + Returns: + True if negative, False otherwise. + """ return self.sign @always_inline def is_positive(self) -> Bool: - """Returns True if this number represents a strictly positive value.""" + """Returns True if this number represents a strictly positive value. + + Returns: + True if strictly positive, False otherwise. + """ return not self.sign and not self.coefficient.is_zero() def is_odd(self) raises -> Bool: - """Returns True if this number represents an odd value.""" + """Returns True if this number represents an odd value. + + Returns: + True if the integer part is odd, False otherwise. + """ if self.scale < 0: return False @@ -1746,7 +2285,11 @@ struct BigDecimal( return True def is_one(self) raises -> Bool: - """Returns True if this number represents one.""" + """Returns True if this number represents one. + + Returns: + True if the value equals 1, False otherwise. + """ if self.sign: return False if self.scale < 0: @@ -1762,7 +2305,11 @@ struct BigDecimal( @always_inline def is_zero(self) -> Bool: - """Returns True if this number represents zero.""" + """Returns True if this number represents zero. + + Returns: + True if the value equals 0, False otherwise. + """ return self.coefficient.is_zero() def normalize(self) raises -> Self: @@ -1778,6 +2325,9 @@ struct BigDecimal( The information conveyed by trailing zeros in the coefficient may be useful for some applications, as it indicates the precision of the number. Normalization may cause loss of this information. + + Returns: + A new `BigDecimal` with trailing zeros removed. """ if self.coefficient.is_zero(): return Self(BigUInt(raw_words=[0]), 0, False) @@ -1820,7 +2370,11 @@ struct BigDecimal( ) def number_of_trailing_zeros(self) -> Int: - """Returns the number of trailing zeros in the coefficient.""" + """Returns the number of trailing zeros in the coefficient. + + Returns: + The count of trailing zero digits. + """ if self.coefficient.is_zero(): return 0 @@ -1853,6 +2407,9 @@ struct BigDecimal( BigDecimal("100.00").number_of_digits() # 5 (trailing zeros in fractional part) BigDecimal("100").number_of_digits() # 3 ``` + + Returns: + The total count of decimal digits in the coefficient. """ return self.coefficient.number_of_digits() diff --git a/src/decimo/bigdecimal/comparison.mojo b/src/decimo/bigdecimal/comparison.mojo index 964edd87..adb3bfb9 100644 --- a/src/decimo/bigdecimal/comparison.mojo +++ b/src/decimo/bigdecimal/comparison.mojo @@ -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() diff --git a/src/decimo/bigdecimal/constants.mojo b/src/decimo/bigdecimal/constants.mojo index 4b39614d..078aeac1 100644 --- a/src/decimo/bigdecimal/constants.mojo +++ b/src/decimo/bigdecimal/constants.mojo @@ -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") @@ -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() @@ -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 @@ -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) @@ -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) @@ -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 diff --git a/src/decimo/bigdecimal/rounding.mojo b/src/decimo/bigdecimal/rounding.mojo index fc1765be..a93ba4e8 100644 --- a/src/decimo/bigdecimal/rounding.mojo +++ b/src/decimo/bigdecimal/rounding.mojo @@ -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 diff --git a/src/decimo/bigdecimal/trigonometric.mojo b/src/decimo/bigdecimal/trigonometric.mojo index c7962bb1..b4245938 100644 --- a/src/decimo/bigdecimal/trigonometric.mojo +++ b/src/decimo/bigdecimal/trigonometric.mojo @@ -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 diff --git a/src/decimo/bigfloat/bigfloat.mojo b/src/decimo/bigfloat/bigfloat.mojo index 5da4473e..ecf4a0d0 100644 --- a/src/decimo/bigfloat/bigfloat.mojo +++ b/src/decimo/bigfloat/bigfloat.mojo @@ -73,17 +73,17 @@ comptime _GUARD_BITS: Int = 64 comptime _BITS_PER_DIGIT: Int = 4 # Default precision in decimal digits, same as BigDecimal. -"""Default precision in decimal digits for BigFloat.""" comptime PRECISION: Int = 28 +"""Default precision in decimal digits for BigFloat.""" # Short alias, like BDec for BigDecimal. -"""Alias for `BigFloat`.""" comptime BFlt = BigFloat +"""Alias for `BigFloat`.""" # Short alias, like Decimal for BigDecimal. # Mojo's built-in floating-point types are all with number suffixes # (e.g., `Float32`, `Float64`), so `Float` is available for BigFloat. -"""Alias for `BigFloat`.""" comptime Float = BigFloat +"""Alias for `BigFloat`.""" fn _dps_to_bits(precision: Int) -> Int: @@ -129,7 +129,9 @@ struct BigFloat(Comparable, Movable, Writable): """ var handle: Int32 + """The MPFR context handle (index into the C wrapper's handle pool).""" var precision: Int + """The number of significant decimal digits.""" # ===------------------------------------------------------------------=== # # Constructors @@ -163,17 +165,31 @@ struct BigFloat(Comparable, Movable, Writable): raise Error("BigFloat: invalid number string: " + value) def __init__(out self, value: Int, precision: Int = PRECISION) raises: - """Creates a BigFloat from an integer.""" + """Creates a BigFloat from an integer. + + Args: + value: The integer to convert. + precision: The number of significant decimal digits. + """ self = Self(String(value), precision) def __init__( out self, decimal: BigDecimal, precision: Int = PRECISION ) raises: - """Creates a BigFloat from a BigDecimal.""" + """Creates a BigFloat from a BigDecimal. + + Args: + decimal: The `BigDecimal` to convert. + precision: The number of significant decimal digits. + """ self = Self(decimal.to_string(), precision) def __init__(out self, *, _handle: Int32, _precision: Int): """Internal: wraps an existing MPFR handle. Caller transfers ownership. + + Args: + _handle: The MPFR context handle to take ownership of. + _precision: The number of significant decimal digits. """ self.handle = _handle self.precision = _precision @@ -183,7 +199,11 @@ struct BigFloat(Comparable, Movable, Writable): # ===------------------------------------------------------------------=== # def __init__(out self, *, deinit take: Self): - """Moves a BigFloat, transferring handle ownership.""" + """Moves a BigFloat, transferring handle ownership. + + Args: + take: The instance to move from. + """ self.handle = take.handle self.precision = take.precision @@ -215,7 +235,14 @@ struct BigFloat(Comparable, Movable, Writable): return result def write_to[W: Writer](self, mut writer: W): - """Writes the decimal string representation to a Writer.""" + """Writes the decimal string representation to a Writer. + + Parameters: + W: A type conforming to the `Writer` interface. + + Args: + writer: The writer instance. + """ if self.handle < 0: writer.write("BigFloat()") return @@ -228,7 +255,14 @@ struct BigFloat(Comparable, Movable, Writable): writer.write(s) def write_repr_to[W: Writer](self, mut writer: W): - """Writes a repr-style string to a Writer.""" + """Writes a repr-style string to a Writer. + + Parameters: + W: A type conforming to the `Writer` interface. + + Args: + writer: The writer instance. + """ if self.handle < 0: writer.write('BigFloat("")') return @@ -328,30 +362,72 @@ struct BigFloat(Comparable, Movable, Writable): # ===------------------------------------------------------------------=== # def __eq__(self, other: Self) -> Bool: - """Returns True if self == other.""" + """Checks whether two BigFloat values are equal. + + Args: + other: The value to compare against. + + Returns: + `True` if the values are equal, `False` otherwise. + """ return mpfrw_cmp(self.handle, other.handle) == 0 def __ne__(self, other: Self) -> Bool: - """Returns True if self != other.""" + """Checks whether two BigFloat values are not equal. + + Args: + other: The value to compare against. + + Returns: + `True` if the values are not equal, `False` otherwise. + """ return mpfrw_cmp(self.handle, other.handle) != 0 def __lt__(self, other: Self) -> Bool: - """Returns True if self < other.""" + """Checks whether this value is strictly less than another. + + Args: + other: The value to compare against. + + Returns: + `True` if `self < other`, `False` otherwise. + """ var c = mpfrw_cmp(self.handle, other.handle) return c != -2 and c < 0 def __le__(self, other: Self) -> Bool: - """Returns True if self <= other.""" + """Checks whether this value is less than or equal to another. + + Args: + other: The value to compare against. + + Returns: + `True` if `self <= other`, `False` otherwise. + """ var c = mpfrw_cmp(self.handle, other.handle) return c != -2 and c <= 0 def __gt__(self, other: Self) -> Bool: - """Returns True if self > other.""" + """Checks whether this value is strictly greater than another. + + Args: + other: The value to compare against. + + Returns: + `True` if `self > other`, `False` otherwise. + """ var c = mpfrw_cmp(self.handle, other.handle) return c != -2 and c > 0 def __ge__(self, other: Self) -> Bool: - """Returns True if self >= other.""" + """Checks whether this value is greater than or equal to another. + + Args: + other: The value to compare against. + + Returns: + `True` if `self >= other`, `False` otherwise. + """ var c = mpfrw_cmp(self.handle, other.handle) return c != -2 and c >= 0 @@ -360,7 +436,11 @@ struct BigFloat(Comparable, Movable, Writable): # ===------------------------------------------------------------------=== # def __neg__(self) raises -> Self: - """Returns -self.""" + """Negates this value. + + Returns: + The negated value. + """ var h = mpfrw_init(_dps_to_bits(self.precision)) if h < 0: raise Error("BigFloat: handle allocation failed") @@ -368,7 +448,11 @@ struct BigFloat(Comparable, Movable, Writable): return Self(_handle=h, _precision=self.precision) def __abs__(self) raises -> Self: - """Returns |self|.""" + """Computes the absolute value. + + Returns: + The absolute value. + """ var h = mpfrw_init(_dps_to_bits(self.precision)) if h < 0: raise Error("BigFloat: handle allocation failed") @@ -380,7 +464,14 @@ struct BigFloat(Comparable, Movable, Writable): # ===------------------------------------------------------------------=== # def __add__(self, other: Self) raises -> Self: - """Returns self + other.""" + """Adds two BigFloat values. + + Args: + other: The right-hand side operand. + + Returns: + The sum. + """ var prec = max(self.precision, other.precision) var h = mpfrw_init(_dps_to_bits(prec)) if h < 0: @@ -389,7 +480,14 @@ struct BigFloat(Comparable, Movable, Writable): return Self(_handle=h, _precision=prec) def __sub__(self, other: Self) raises -> Self: - """Returns self - other.""" + """Subtracts two BigFloat values. + + Args: + other: The right-hand side operand. + + Returns: + The difference. + """ var prec = max(self.precision, other.precision) var h = mpfrw_init(_dps_to_bits(prec)) if h < 0: @@ -398,7 +496,14 @@ struct BigFloat(Comparable, Movable, Writable): return Self(_handle=h, _precision=prec) def __mul__(self, other: Self) raises -> Self: - """Returns self * other.""" + """Multiplies two BigFloat values. + + Args: + other: The right-hand side operand. + + Returns: + The product. + """ var prec = max(self.precision, other.precision) var h = mpfrw_init(_dps_to_bits(prec)) if h < 0: @@ -407,7 +512,14 @@ struct BigFloat(Comparable, Movable, Writable): return Self(_handle=h, _precision=prec) def __truediv__(self, other: Self) raises -> Self: - """Returns self / other.""" + """Divides two BigFloat values. + + Args: + other: The right-hand side operand. + + Returns: + The quotient. + """ var prec = max(self.precision, other.precision) var h = mpfrw_init(_dps_to_bits(prec)) if h < 0: @@ -416,7 +528,14 @@ struct BigFloat(Comparable, Movable, Writable): return Self(_handle=h, _precision=prec) def __pow__(self, exponent: Self) raises -> Self: - """Returns self ** exponent.""" + """Raises this value to the given power. + + Args: + exponent: The exponent to raise to. + + Returns: + The result of `self` raised to `exponent`. + """ return self.power(exponent) # ===------------------------------------------------------------------=== # @@ -424,7 +543,11 @@ struct BigFloat(Comparable, Movable, Writable): # ===------------------------------------------------------------------=== # def sqrt(self) raises -> Self: - """Computes the square root.""" + """Computes the square root. + + Returns: + The square root of this value. + """ var h = mpfrw_init(_dps_to_bits(self.precision)) if h < 0: raise Error("BigFloat: handle allocation failed") @@ -432,7 +555,11 @@ struct BigFloat(Comparable, Movable, Writable): return Self(_handle=h, _precision=self.precision) def exp(self) raises -> Self: - """Computes e^self.""" + """Computes the exponential function e^self. + + Returns: + The exponential of this value. + """ var h = mpfrw_init(_dps_to_bits(self.precision)) if h < 0: raise Error("BigFloat: handle allocation failed") @@ -440,7 +567,11 @@ struct BigFloat(Comparable, Movable, Writable): return Self(_handle=h, _precision=self.precision) def ln(self) raises -> Self: - """Computes the natural logarithm.""" + """Computes the natural logarithm. + + Returns: + The natural logarithm of this value. + """ var h = mpfrw_init(_dps_to_bits(self.precision)) if h < 0: raise Error("BigFloat: handle allocation failed") @@ -448,7 +579,11 @@ struct BigFloat(Comparable, Movable, Writable): return Self(_handle=h, _precision=self.precision) def sin(self) raises -> Self: - """Computes the sine.""" + """Computes the sine. + + Returns: + The sine of this value. + """ var h = mpfrw_init(_dps_to_bits(self.precision)) if h < 0: raise Error("BigFloat: handle allocation failed") @@ -456,7 +591,11 @@ struct BigFloat(Comparable, Movable, Writable): return Self(_handle=h, _precision=self.precision) def cos(self) raises -> Self: - """Computes the cosine.""" + """Computes the cosine. + + Returns: + The cosine of this value. + """ var h = mpfrw_init(_dps_to_bits(self.precision)) if h < 0: raise Error("BigFloat: handle allocation failed") @@ -464,7 +603,11 @@ struct BigFloat(Comparable, Movable, Writable): return Self(_handle=h, _precision=self.precision) def tan(self) raises -> Self: - """Computes the tangent.""" + """Computes the tangent. + + Returns: + The tangent of this value. + """ var h = mpfrw_init(_dps_to_bits(self.precision)) if h < 0: raise Error("BigFloat: handle allocation failed") @@ -472,7 +615,14 @@ struct BigFloat(Comparable, Movable, Writable): return Self(_handle=h, _precision=self.precision) def power(self, exponent: Self) raises -> Self: - """Computes self raised to the given exponent.""" + """Computes self raised to the given exponent. + + Args: + exponent: The exponent to raise to. + + Returns: + The result of `self` raised to `exponent`. + """ var prec = max(self.precision, exponent.precision) var h = mpfrw_init(_dps_to_bits(prec)) if h < 0: @@ -481,7 +631,14 @@ struct BigFloat(Comparable, Movable, Writable): return Self(_handle=h, _precision=prec) def root(self, n: UInt32) raises -> Self: - """Computes the n-th root.""" + """Computes the n-th root. + + Args: + n: The root degree (e.g. 2 for square root, 3 for cube root). + + Returns: + The n-th root of this value. + """ var h = mpfrw_init(_dps_to_bits(self.precision)) if h < 0: raise Error("BigFloat: handle allocation failed") @@ -490,7 +647,14 @@ struct BigFloat(Comparable, Movable, Writable): @staticmethod def pi(precision: Int = PRECISION) raises -> BigFloat: - """Returns π to the specified number of decimal digits.""" + """Returns π to the specified number of decimal digits. + + Args: + precision: The number of significant decimal digits. + + Returns: + A `BigFloat` containing π at the requested precision. + """ if not mpfrw_available(): raise Error( "BigFloat requires MPFR" diff --git a/src/decimo/bigint/arithmetics.mojo b/src/decimo/bigint/arithmetics.mojo index a9931a3b..9708fade 100644 --- a/src/decimo/bigint/arithmetics.mojo +++ b/src/decimo/bigint/arithmetics.mojo @@ -43,13 +43,16 @@ from decimo.errors import DecimoError # Karatsuba cutoff: operands with this many words or fewer use schoolbook. # Tuned for Apple Silicon arm64. Adjust if benchmarking shows a better value. comptime CUTOFF_KARATSUBA: Int = 48 +"""The minimum number of words above which Karatsuba multiplication is used.""" # SIMD vector width: 4 x UInt32 = 128-bit, supported natively on arm64 NEON. comptime VECTOR_WIDTH: Int = 4 +"""The SIMD vector width used for vectorized operations.""" # Burnikel-Ziegler cutoff: divisors with this many words or fewer use # Knuth D (schoolbook). Must be even for the recursive halving to work. comptime CUTOFF_BURNIKEL_ZIEGLER: Int = 64 +"""The minimum number of words above which Burnikel-Ziegler division is used.""" # ===----------------------------------------------------------------------=== # @@ -2327,7 +2330,7 @@ def power(base: BigInt, exponent: Int) raises -> BigInt: multiplications. Args: - base: The base value. + base: The `BigInt` to raise to a power. exponent: The non-negative exponent. Returns: diff --git a/src/decimo/bigint/bigint.mojo b/src/decimo/bigint/bigint.mojo index 1b11d69d..39c7641d 100644 --- a/src/decimo/bigint/bigint.mojo +++ b/src/decimo/bigint/bigint.mojo @@ -108,19 +108,31 @@ struct BigInt( @always_inline @staticmethod def zero() -> Self: - """Returns a BigInt with value 0.""" + """Returns a BigInt with value 0. + + Returns: + A `BigInt` with value 0. + """ return Self() @always_inline @staticmethod def one() -> Self: - """Returns a BigInt with value 1.""" + """Returns a BigInt with value 1. + + Returns: + A `BigInt` with value 1. + """ return Self(raw_words=[UInt32(1)], sign=False) @always_inline @staticmethod def negative_one() -> Self: - """Returns a BigInt with value -1.""" + """Returns a BigInt with value -1. + + Returns: + A `BigInt` with value -1. + """ return Self(raw_words=[UInt32(1)], sign=True) # ===------------------------------------------------------------------=== # @@ -186,6 +198,9 @@ struct BigInt( Constraints: The dtype of the scalar must be integral. + + Args: + value: The integral scalar value to convert. """ self = Self.from_integral_scalar(value) @@ -248,6 +263,9 @@ struct BigInt( Returns: The BigInt representation of the Scalar value. + + Parameters: + dtype: The data type of the scalar value. """ if value == 0: @@ -554,6 +572,9 @@ struct BigInt( def __int__(self) raises -> Int: """Returns the number as Int. See `to_int()` for more information. + + Returns: + The `Int` representation. """ return self.to_int() @@ -570,11 +591,25 @@ struct BigInt( return Float64(self.to_string()) def write_repr_to[W: Writer](self, mut writer: W): - """Writes the debug representation to a writer.""" + """Writes the debug representation to a writer. + + Parameters: + W: A type conforming to the `Writer` interface. + + Args: + writer: The writer instance. + """ writer.write('BigInt("', self.to_string(), '")') def write_to[W: Writer](self, mut writer: W): - """Writes the decimal string representation to a writer.""" + """Writes the decimal string representation to a writer. + + Parameters: + W: A type conforming to the `Writer` interface. + + Args: + writer: The writer instance. + """ writer.write(self.to_string()) # ===------------------------------------------------------------------=== # @@ -701,6 +736,12 @@ struct BigInt( """Returns the decimal string representation of the BigInt. Deprecated: Use ``to_string(line_width=...)`` instead. + + Args: + line_width: The maximum line width for the output. + + Returns: + The decimal string representation. """ return self.to_string(line_width=line_width) @@ -804,13 +845,21 @@ struct BigInt( # ===------------------------------------------------------------------=== # def __neg__(self) -> Self: - """Returns the negation of the BigInt.""" + """Returns the negation of the BigInt. + + Returns: + The negated value. + """ if self.is_zero(): return Self() return Self(raw_words=self.words.copy(), sign=not self.sign) def __abs__(self) -> Self: - """Returns the absolute value of the BigInt.""" + """Returns the absolute value of the BigInt. + + Returns: + The absolute value. + """ return Self(raw_words=self.words.copy(), sign=False) @always_inline @@ -818,6 +867,9 @@ struct BigInt( """Returns True if the number is nonzero. This enables `if n:` syntax, consistent with Python's `int`. + + Returns: + `True` if non-zero, `False` otherwise. """ return not self.is_zero() @@ -826,6 +878,9 @@ struct BigInt( """Returns the number unchanged (unary plus). This enables `+n` syntax, consistent with Python's `int`. + + Returns: + A copy of this value. """ return Self(raw_words=self.words.copy(), sign=self.sign) @@ -834,6 +889,9 @@ struct BigInt( """Returns self unchanged. Integers are already integers. This enables `math.ceil()` compatibility with Python's `int`. + + Returns: + A copy of this value. """ return Self(raw_words=self.words.copy(), sign=self.sign) @@ -842,6 +900,9 @@ struct BigInt( """Returns self unchanged. Integers are already integers. This enables `math.floor()` compatibility with Python's `int`. + + Returns: + A copy of this value. """ return Self(raw_words=self.words.copy(), sign=self.sign) @@ -850,6 +911,9 @@ struct BigInt( """Returns self unchanged. Integers are already integers. This enables `math.trunc()` compatibility with Python's `int`. + + Returns: + A copy of this value. """ return Self(raw_words=self.words.copy(), sign=self.sign) @@ -861,18 +925,50 @@ struct BigInt( @always_inline def __add__(self, other: Self) -> Self: + """Adds two values. + + Args: + other: The right-hand side operand. + + Returns: + The sum of the two values. + """ return decimo.bigint.arithmetics.add(self, other) @always_inline def __sub__(self, other: Self) -> Self: + """Subtracts two values. + + Args: + other: The right-hand side operand. + + Returns: + The difference of the two values. + """ return decimo.bigint.arithmetics.subtract(self, other) @always_inline def __mul__(self, other: Self) -> Self: + """Multiplies two values. + + Args: + other: The right-hand side operand. + + Returns: + The product of the two values. + """ return decimo.bigint.arithmetics.multiply(self, other) @always_inline def __floordiv__(self, other: Self) raises -> Self: + """Divides two values using floor division. + + Args: + other: The right-hand side operand. + + Returns: + The quotient, rounded toward negative infinity. + """ try: return decimo.bigint.arithmetics.floor_divide(self, other) except e: @@ -887,6 +983,14 @@ struct BigInt( @always_inline def __mod__(self, other: Self) raises -> Self: + """Returns the remainder of division. + + Args: + other: The right-hand side operand. + + Returns: + The floor remainder with the same sign as the divisor. + """ try: return decimo.bigint.arithmetics.floor_modulo(self, other) except e: @@ -901,6 +1005,14 @@ struct BigInt( @always_inline def __divmod__(self, other: Self) raises -> Tuple[Self, Self]: + """Returns the quotient and remainder of division. + + Args: + other: The right-hand side operand. + + Returns: + A tuple of (quotient, remainder) using floor division. + """ try: return decimo.bigint.arithmetics.floor_divmod(self, other) except e: @@ -915,20 +1027,50 @@ struct BigInt( @always_inline def __pow__(self, exponent: Self) raises -> Self: + """Raises to a power. + + Args: + exponent: The exponent. + + Returns: + The result of raising to the given power. + """ return self.power(exponent) @always_inline def __pow__(self, exponent: Int) raises -> Self: + """Raises to a power. + + Args: + exponent: The exponent. + + Returns: + The result of raising to the given power. + """ return self.power(exponent) @always_inline def __lshift__(self, shift: Int) -> Self: - """Returns self << shift (multiply by 2^shift).""" + """Returns self << shift (multiply by 2^shift). + + Args: + shift: The number of bits to shift left. + + Returns: + The left-shifted value. + """ return decimo.bigint.arithmetics.left_shift(self, shift) @always_inline def __rshift__(self, shift: Int) -> Self: - """Returns self >> shift (floor divide by 2^shift).""" + """Returns self >> shift (floor divide by 2^shift). + + Args: + shift: The number of bits to shift right. + + Returns: + The right-shifted value. + """ return decimo.bigint.arithmetics.right_shift(self, shift) # ===------------------------------------------------------------------=== # @@ -937,30 +1079,86 @@ struct BigInt( @always_inline def __radd__(self, other: Self) -> Self: + """Adds two values (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The sum of the two values. + """ return decimo.bigint.arithmetics.add(self, other) @always_inline def __rsub__(self, other: Self) -> Self: + """Subtracts two values (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The difference of the two values. + """ return decimo.bigint.arithmetics.subtract(other, self) @always_inline def __rmul__(self, other: Self) -> Self: + """Multiplies two values (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The product of the two values. + """ return decimo.bigint.arithmetics.multiply(self, other) @always_inline def __rfloordiv__(self, other: Self) raises -> Self: + """Divides two values using floor division (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The quotient, rounded toward negative infinity. + """ return decimo.bigint.arithmetics.floor_divide(other, self) @always_inline def __rmod__(self, other: Self) raises -> Self: + """Returns the remainder of division (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The floor remainder with the same sign as the divisor. + """ return decimo.bigint.arithmetics.floor_modulo(other, self) @always_inline def __rdivmod__(self, other: Self) raises -> Tuple[Self, Self]: + """Returns the quotient and remainder of division (reflected). + + Args: + other: The left-hand side operand. + + Returns: + A tuple of (quotient, remainder) using floor division. + """ return decimo.bigint.arithmetics.floor_divmod(other, self) @always_inline def __rpow__(self, base: Self) raises -> Self: + """Raises to a power (reflected). + + Args: + base: The base to raise to this power. + + Returns: + The result of raising the base to this power. + """ return base.power(self) # ===------------------------------------------------------------------=== # @@ -970,42 +1168,74 @@ struct BigInt( @always_inline def __iadd__(mut self, other: Self): - """True in-place addition: mutates self.words directly.""" + """True in-place addition: mutates self.words directly. + + Args: + other: The right-hand side operand. + """ decimo.bigint.arithmetics.add_inplace(self, other) @always_inline def __iadd__(mut self, other: Int): - """True in-place addition with Int: mutates self.words directly.""" + """True in-place addition with Int: mutates self.words directly. + + Args: + other: The right-hand side operand. + """ decimo.bigint.arithmetics.add_inplace_int(self, other) @always_inline def __isub__(mut self, other: Self): - """True in-place subtraction: mutates self.words directly.""" + """True in-place subtraction: mutates self.words directly. + + Args: + other: The right-hand side operand. + """ decimo.bigint.arithmetics.subtract_inplace(self, other) @always_inline def __imul__(mut self, other: Self): - """True in-place multiplication: computes product into self.words.""" + """True in-place multiplication: computes product into self.words. + + Args: + other: The right-hand side operand. + """ decimo.bigint.arithmetics.multiply_inplace(self, other) @always_inline def __ifloordiv__(mut self, other: Self) raises: - """True in-place floor division: moves quotient into self.words.""" + """True in-place floor division: moves quotient into self.words. + + Args: + other: The right-hand side operand. + """ decimo.bigint.arithmetics.floor_divide_inplace(self, other) @always_inline def __imod__(mut self, other: Self) raises: - """True in-place modulo: moves remainder into self.words.""" + """True in-place modulo: moves remainder into self.words. + + Args: + other: The right-hand side operand. + """ decimo.bigint.arithmetics.floor_modulo_inplace(self, other) @always_inline def __ilshift__(mut self, shift: Int): - """True in-place left shift: mutates self.words directly.""" + """True in-place left shift: mutates self.words directly. + + Args: + shift: The number of bits to shift left. + """ decimo.bigint.arithmetics.left_shift_inplace(self, shift) @always_inline def __irshift__(mut self, shift: Int): - """True in-place right shift: mutates self.words directly.""" + """True in-place right shift: mutates self.words directly. + + Args: + shift: The number of bits to shift right. + """ decimo.bigint.arithmetics.right_shift_inplace(self, shift) # ===------------------------------------------------------------------=== # @@ -1015,64 +1245,148 @@ struct BigInt( @always_inline def __gt__(self, other: Self) -> Bool: - """Returns True if self > other.""" + """Returns True if self > other. + + Args: + other: The value to compare against. + + Returns: + `True` if self is greater than other, `False` otherwise. + """ return decimo.bigint.comparison.greater(self, other) @always_inline def __gt__(self, other: Int) -> Bool: - """Returns True if self > other.""" + """Returns True if self > other. + + Args: + other: The value to compare against. + + Returns: + `True` if self is greater than other, `False` otherwise. + """ return decimo.bigint.comparison.greater(self, Self.from_int(other)) @always_inline def __ge__(self, other: Self) -> Bool: - """Returns True if self >= other.""" + """Returns True if self >= other. + + Args: + other: The value to compare against. + + Returns: + `True` if self is greater than or equal to other, `False` otherwise. + """ return decimo.bigint.comparison.greater_equal(self, other) @always_inline def __ge__(self, other: Int) -> Bool: - """Returns True if self >= other.""" + """Returns True if self >= other. + + Args: + other: The value to compare against. + + Returns: + `True` if self is greater than or equal to other, `False` otherwise. + """ return decimo.bigint.comparison.greater_equal( self, Self.from_int(other) ) @always_inline def __lt__(self, other: Self) -> Bool: - """Returns True if self < other.""" + """Returns True if self < other. + + Args: + other: The value to compare against. + + Returns: + `True` if self is less than other, `False` otherwise. + """ return decimo.bigint.comparison.less(self, other) @always_inline def __lt__(self, other: Int) -> Bool: - """Returns True if self < other.""" + """Returns True if self < other. + + Args: + other: The value to compare against. + + Returns: + `True` if self is less than other, `False` otherwise. + """ return decimo.bigint.comparison.less(self, Self.from_int(other)) @always_inline def __le__(self, other: Self) -> Bool: - """Returns True if self <= other.""" + """Returns True if self <= other. + + Args: + other: The value to compare against. + + Returns: + `True` if self is less than or equal to other, `False` otherwise. + """ return decimo.bigint.comparison.less_equal(self, other) @always_inline def __le__(self, other: Int) -> Bool: - """Returns True if self <= other.""" + """Returns True if self <= other. + + Args: + other: The value to compare against. + + Returns: + `True` if self is less than or equal to other, `False` otherwise. + """ return decimo.bigint.comparison.less_equal(self, Self.from_int(other)) @always_inline def __eq__(self, other: Self) -> Bool: - """Returns True if self == other.""" + """Returns True if self == other. + + Args: + other: The value to compare against. + + Returns: + `True` if the two values are equal, `False` otherwise. + """ return decimo.bigint.comparison.equal(self, other) @always_inline def __eq__(self, other: Int) -> Bool: - """Returns True if self == other.""" + """Returns True if self == other. + + Args: + other: The value to compare against. + + Returns: + `True` if the two values are equal, `False` otherwise. + """ return decimo.bigint.comparison.equal(self, Self.from_int(other)) @always_inline def __ne__(self, other: Self) -> Bool: - """Returns True if self != other.""" + """Returns True if self != other. + + Args: + other: The value to compare against. + + Returns: + `True` if the two values are not equal, `False` otherwise. + """ return decimo.bigint.comparison.not_equal(self, other) @always_inline def __ne__(self, other: Int) -> Bool: - """Returns True if self != other.""" + """Returns True if self != other. + + Args: + other: The value to compare against. + + Returns: + `True` if the two values are not equal, `False` otherwise. + """ return decimo.bigint.comparison.not_equal(self, Self.from_int(other)) # ===------------------------------------------------------------------=== # @@ -1083,6 +1397,12 @@ struct BigInt( def truncate_divide(self, other: Self) raises -> Self: """Performs a truncated division of two BigInt numbers. See `truncate_divide()` for more information. + + Args: + other: The divisor. + + Returns: + The quotient, truncated toward zero. """ return decimo.bigint.arithmetics.truncate_divide(self, other) @@ -1090,6 +1410,12 @@ struct BigInt( def floor_modulo(self, other: Self) raises -> Self: """Performs a floor modulo of two BigInt numbers. See `floor_modulo()` for more information. + + Args: + other: The divisor. + + Returns: + The floor remainder with the same sign as the divisor. """ return decimo.bigint.arithmetics.floor_modulo(self, other) @@ -1097,6 +1423,12 @@ struct BigInt( def truncate_modulo(self, other: Self) raises -> Self: """Performs a truncated modulo of two BigInt numbers. See `truncate_modulo()` for more information. + + Args: + other: The divisor. + + Returns: + The truncated remainder with the same sign as the dividend. """ return decimo.bigint.arithmetics.truncate_modulo(self, other) @@ -1165,6 +1497,12 @@ struct BigInt( def compare_magnitudes(self, other: Self) -> Int8: """Compares the magnitudes (absolute values) of two BigInt numbers. See `compare_magnitudes()` for more information. + + Args: + other: The value to compare against. + + Returns: + 1 if |self| > |other|, 0 if equal, -1 if |self| < |other|. """ return decimo.bigint.comparison.compare_magnitudes(self, other) @@ -1172,6 +1510,12 @@ struct BigInt( def compare(self, other: Self) -> Int8: """Compares two BigInt numbers. See `compare()` for more information. + + Args: + other: The value to compare against. + + Returns: + 1 if self > other, 0 if equal, -1 if self < other. """ return decimo.bigint.comparison.compare(self, other) @@ -1182,54 +1526,109 @@ struct BigInt( @always_inline def __and__(self, other: Self) -> Self: """Returns self & other (bitwise AND, Python two's complement semantics). + + Args: + other: The right-hand side operand. + + Returns: + The bitwise AND of the two values. """ return decimo.bigint.bitwise.bitwise_and(self, other) @always_inline def __and__(self, other: Int) -> Self: - """Returns self & other where other is an Int.""" + """Returns self & other where other is an Int. + + Args: + other: The right-hand side operand. + + Returns: + The bitwise AND of the two values. + """ return decimo.bigint.bitwise.bitwise_and(self, Self(other)) @always_inline def __or__(self, other: Self) -> Self: """Returns self | other (bitwise OR, Python two's complement semantics). + + Args: + other: The right-hand side operand. + + Returns: + The bitwise OR of the two values. """ return decimo.bigint.bitwise.bitwise_or(self, other) @always_inline def __or__(self, other: Int) -> Self: - """Returns self | other where other is an Int.""" + """Returns self | other where other is an Int. + + Args: + other: The right-hand side operand. + + Returns: + The bitwise OR of the two values. + """ return decimo.bigint.bitwise.bitwise_or(self, Self(other)) @always_inline def __xor__(self, other: Self) -> Self: """Returns self ^ other (bitwise XOR, Python two's complement semantics). + + Args: + other: The right-hand side operand. + + Returns: + The bitwise XOR of the two values. """ return decimo.bigint.bitwise.bitwise_xor(self, other) @always_inline def __xor__(self, other: Int) -> Self: - """Returns self ^ other where other is an Int.""" + """Returns self ^ other where other is an Int. + + Args: + other: The right-hand side operand. + + Returns: + The bitwise XOR of the two values. + """ return decimo.bigint.bitwise.bitwise_xor(self, Self(other)) @always_inline def __invert__(self) -> Self: - """Returns ~self (bitwise NOT, Python two's complement semantics).""" + """Returns ~self (bitwise NOT, Python two's complement semantics). + + Returns: + The bitwise complement, equal to -(self + 1). + """ return decimo.bigint.bitwise.bitwise_not(self) @always_inline def __iand__(mut self, other: Self): - """True in-place bitwise AND: mutates self.words directly.""" + """True in-place bitwise AND: mutates self.words directly. + + Args: + other: The right-hand side operand. + """ decimo.bigint.bitwise.bitwise_and_inplace(self, other) @always_inline def __ior__(mut self, other: Self): - """True in-place bitwise OR: mutates self.words directly.""" + """True in-place bitwise OR: mutates self.words directly. + + Args: + other: The right-hand side operand. + """ decimo.bigint.bitwise.bitwise_or_inplace(self, other) @always_inline def __ixor__(mut self, other: Self): - """True in-place bitwise XOR: mutates self.words directly.""" + """True in-place bitwise XOR: mutates self.words directly. + + Args: + other: The right-hand side operand. + """ decimo.bigint.bitwise.bitwise_xor_inplace(self, other) # ===------------------------------------------------------------------=== # @@ -1238,7 +1637,14 @@ struct BigInt( @always_inline def gcd(self, other: Self) -> Self: - """Returns the greatest common divisor of self and other.""" + """Returns the greatest common divisor of self and other. + + Args: + other: The second value for the GCD computation. + + Returns: + The greatest common divisor of the two values. + """ return decimo.bigint.number_theory.gcd(self, other) @always_inline @@ -1252,18 +1658,35 @@ struct BigInt( Returns: A tuple (g, x, y) where g is the gcd of self and other, and x and y are the coefficients satisfying the equation. + + Args: + other: The second value for the extended GCD computation. """ return decimo.bigint.number_theory.extended_gcd(self, other) @always_inline def lcm(self, other: Self) raises -> Self: - """Returns the least common multiple of self and other.""" + """Returns the least common multiple of self and other. + + Args: + other: The second value for the LCM computation. + + Returns: + The least common multiple of the two values. + """ return decimo.bigint.number_theory.lcm(self, other) @always_inline def mod_pow(self, exponent: Self, modulus: Self) raises -> Self: """Returns (self ** exponent) % modulus efficiently using modular exponentiation. + + Args: + exponent: The exponent. + modulus: The modulus. + + Returns: + The result of (self ** exponent) % modulus. """ return decimo.bigint.number_theory.mod_pow(self, exponent, modulus) @@ -1271,6 +1694,13 @@ struct BigInt( def mod_pow(self, exponent: Int, modulus: Self) raises -> Self: """Returns (self ** exponent) % modulus efficiently using modular exponentiation. + + Args: + exponent: The exponent. + modulus: The modulus. + + Returns: + The result of (self ** exponent) % modulus. """ return decimo.bigint.number_theory.mod_pow( self, Self.from_int(exponent), modulus @@ -1280,6 +1710,12 @@ struct BigInt( def mod_inverse(self, modulus: Self) raises -> Self: """Returns the modular inverse of self modulo modulus, i.e. a number x such that (self * x) % modulus == 1. + + Args: + modulus: The modulus. + + Returns: + The modular multiplicative inverse. """ return decimo.bigint.number_theory.mod_inverse(self, modulus) @@ -1289,7 +1725,11 @@ struct BigInt( @always_inline def is_zero(self) -> Bool: - """Returns True if the value is zero.""" + """Returns True if the value is zero. + + Returns: + `True` if the value is zero, `False` otherwise. + """ if len(self.words) == 1 and self.words[0] == 0: return True for word in self.words: @@ -1299,20 +1739,36 @@ struct BigInt( @always_inline def is_negative(self) -> Bool: - """Returns True if the value is strictly negative.""" + """Returns True if the value is strictly negative. + + Returns: + `True` if the value is negative, `False` otherwise. + """ return self.sign and not self.is_zero() @always_inline def is_positive(self) -> Bool: - """Returns True if the value is strictly positive.""" + """Returns True if the value is strictly positive. + + Returns: + `True` if the value is positive, `False` otherwise. + """ return not self.sign and not self.is_zero() def is_one(self) -> Bool: - """Returns True if the value is exactly 1.""" + """Returns True if the value is exactly 1. + + Returns: + `True` if the value is 1, `False` otherwise. + """ return not self.sign and len(self.words) == 1 and self.words[0] == 1 def is_one_or_minus_one(self) -> Bool: - """Returns True if the value is 1 or -1.""" + """Returns True if the value is 1 or -1. + + Returns: + `True` if the value is 1 or -1, `False` otherwise. + """ return len(self.words) == 1 and self.words[0] == 1 def bit_length(self) -> Int: @@ -1364,7 +1820,11 @@ struct BigInt( return count def number_of_words(self) -> Int: - """Returns the number of words in the magnitude.""" + """Returns the number of words in the magnitude. + + Returns: + The number of `UInt32` words used to represent the magnitude. + """ return len(self.words) def number_of_digits(self) -> Int: @@ -1372,6 +1832,9 @@ struct BigInt( Notes: Zero has 1 digit. + + Returns: + The number of decimal digits. """ if self.is_zero(): return 1 @@ -1384,7 +1847,11 @@ struct BigInt( # ===------------------------------------------------------------------=== # def copy(self) -> Self: - """Returns a deep copy of this BigInt.""" + """Returns a deep copy of this BigInt. + + Returns: + A new `BigInt` with the same value. + """ var new_words = List[UInt32](capacity=len(self.words)) for word in self.words: new_words.append(word) @@ -1400,7 +1867,11 @@ struct BigInt( self.sign = False def internal_representation(self) -> String: - """Returns the internal representation details as a String.""" + """Returns the internal representation details as a String. + + Returns: + A string showing the sign and word-level magnitude representation. + """ # Collect all labels to find max width var fixed_labels = List[String]() fixed_labels.append("number:") diff --git a/src/decimo/bigint/bitwise.mojo b/src/decimo/bigint/bitwise.mojo index b4667cbd..ee8b0225 100644 --- a/src/decimo/bigint/bitwise.mojo +++ b/src/decimo/bigint/bitwise.mojo @@ -327,17 +327,41 @@ def _binary_bitwise_op_inplace[ def bitwise_and(a: BigInt, b: BigInt) -> BigInt: - """Returns a & b using Python-compatible two's complement semantics.""" + """Returns a & b using Python-compatible two's complement semantics. + + Args: + a: The first operand. + b: The second operand. + + Returns: + The bitwise AND of the two values. + """ return _binary_bitwise_op["and"](a, b) def bitwise_or(a: BigInt, b: BigInt) -> BigInt: - """Returns a | b using Python-compatible two's complement semantics.""" + """Returns a | b using Python-compatible two's complement semantics. + + Args: + a: The first operand. + b: The second operand. + + Returns: + The bitwise OR of the two values. + """ return _binary_bitwise_op["or"](a, b) def bitwise_xor(a: BigInt, b: BigInt) -> BigInt: - """Returns a ^ b using Python-compatible two's complement semantics.""" + """Returns a ^ b using Python-compatible two's complement semantics. + + Args: + a: The first operand. + b: The second operand. + + Returns: + The bitwise XOR of the two values. + """ return _binary_bitwise_op["xor"](a, b) @@ -348,6 +372,12 @@ def bitwise_not(x: BigInt) -> BigInt: For non-negative x: result is -(x+1), always negative (except ~(-1) = 0). For negative x (x = -|x|): result is |x| - 1, always non-negative. + + Args: + x: The value to invert. + + Returns: + The bitwise complement. """ if not x.sign: # ~non_negative = -(x + 1) @@ -384,18 +414,30 @@ def bitwise_not(x: BigInt) -> BigInt: def bitwise_and_inplace(mut a: BigInt, read b: BigInt): - """Performs a &= b in-place using Python-compatible two's complement - semantics.""" + """Performs `a &= b` in-place using Python-compatible two's complement semantics. + + Args: + a: The left-hand side operand, modified in place. + b: The right-hand side operand. + """ _binary_bitwise_op_inplace["and"](a, b) def bitwise_or_inplace(mut a: BigInt, read b: BigInt): - """Performs a |= b in-place using Python-compatible two's complement - semantics.""" + """Performs `a |= b` in-place using Python-compatible two's complement semantics. + + Args: + a: The left-hand side operand, modified in place. + b: The right-hand side operand. + """ _binary_bitwise_op_inplace["or"](a, b) def bitwise_xor_inplace(mut a: BigInt, read b: BigInt): - """Performs a ^= b in-place using Python-compatible two's complement - semantics.""" + """Performs `a ^= b` in-place using Python-compatible two's complement semantics. + + Args: + a: The left-hand side operand, modified in place. + b: The right-hand side operand. + """ _binary_bitwise_op_inplace["xor"](a, b) diff --git a/src/decimo/bigint10/bigint10.mojo b/src/decimo/bigint10/bigint10.mojo index 457b13d3..0f74e7aa 100644 --- a/src/decimo/bigint10/bigint10.mojo +++ b/src/decimo/bigint10/bigint10.mojo @@ -53,9 +53,9 @@ struct BigInt10( """ var magnitude: BigUInt - """The magnitude of the BigInt10.""" + """The absolute value stored as a `BigUInt`.""" var sign: Bool - """Sign information.""" + """The sign flag. `True` if negative, `False` if non-negative.""" # ===------------------------------------------------------------------=== # # Constructors and life time dunder methods @@ -75,7 +75,11 @@ struct BigInt10( @implicit def __init__(out self, magnitude: BigUInt): - """Constructs a BigInt10 from a BigUInt object.""" + """Constructs a BigInt10 from a BigUInt object. + + Args: + magnitude: The `BigUInt` to construct from. + """ self.magnitude = magnitude.copy() self.sign = False @@ -144,6 +148,9 @@ struct BigInt10( def __init__(out self, value: String) raises: """Initializes a BigInt10 from a string representation. See `from_string()` for more information. + + Args: + value: The string representation of the integer. """ try: self = Self.from_string(value) @@ -156,6 +163,9 @@ struct BigInt10( def __init__(out self, value: Int): """Initializes a BigInt10 from an `Int` object. See `from_int()` for more information. + + Args: + value: The integer value to convert. """ self = Self.from_int(value) @@ -166,11 +176,18 @@ struct BigInt10( Constraints: The dtype of the scalar must be integral. + + Args: + value: The scalar value to convert. """ self = Self.from_integral_scalar(value) def __init__(out self, *, py: PythonObject) raises: - """Constructs a BigInt10 from a Python int object.""" + """Constructs a BigInt10 from a Python int object. + + Args: + py: The Python integer object to convert from. + """ self = Self.from_python_int(py) # ===------------------------------------------------------------------=== # @@ -228,6 +245,9 @@ struct BigInt10( Notes: This method validates whether the words are smaller than `999_999_999`. + + Returns: + A new `BigInt10` from the given words. """ var list_of_words = List[UInt32](capacity=len(words)) @@ -246,7 +266,14 @@ struct BigInt10( @staticmethod def from_int(value: Int) -> Self: - """Creates a BigInt10 from an integer.""" + """Creates a BigInt10 from an integer. + + Args: + value: The integer value to convert. + + Returns: + A new `BigInt10` from the given integer. + """ if value == 0: return Self() @@ -291,6 +318,9 @@ struct BigInt10( Returns: The BigInt10 representation of the Scalar value. + + Parameters: + dtype: The data type of the input scalar. """ comptime assert dtype.is_integral(), "dtype must be integral." @@ -381,11 +411,21 @@ struct BigInt10( def __int__(self) raises -> Int: """Returns the number as Int. See `to_int()` for more information. + + Returns: + The `Int` representation of this value. """ return self.to_int() def write_repr_to[W: Writer](self, mut writer: W): - """Writes the debug representation to a writer.""" + """Writes the debug representation to a writer. + + Parameters: + W: A type conforming to the `Writer` interface. + + Args: + writer:: The writer instance. + """ writer.write('BigInt10("', self.to_string(), '")') # ===------------------------------------------------------------------=== # @@ -395,6 +435,12 @@ struct BigInt10( def write_to[W: Writer](self, mut writer: W): """Writes the BigInt10 to a writer. This implement the `write` method of the `Writer` trait. + + Parameters: + W: A type conforming to the `Writer` interface. + + Args: + writer:: The writer instance. """ writer.write(self.to_string()) @@ -503,6 +549,9 @@ struct BigInt10( def __abs__(self) -> Self: """Returns the absolute value of this number. See `absolute()` for more information. + + Returns: + The absolute value. """ return decimo.bigint10.arithmetics.absolute(self) @@ -510,6 +559,9 @@ struct BigInt10( def __neg__(self) -> Self: """Returns the negation of this number. See `negative()` for more information. + + Returns: + The negated value. """ return decimo.bigint10.arithmetics.negative(self) @@ -521,18 +573,50 @@ struct BigInt10( @always_inline def __add__(self, other: Self) -> Self: + """Adds two values. + + Args: + other: The right-hand side operand. + + Returns: + The sum of the two values. + """ return decimo.bigint10.arithmetics.add(self, other) @always_inline def __sub__(self, other: Self) -> Self: + """Subtracts two values. + + Args: + other: The right-hand side operand. + + Returns: + The difference of the two values. + """ return decimo.bigint10.arithmetics.subtract(self, other) @always_inline def __mul__(self, other: Self) -> Self: + """Multiplies two values. + + Args: + other: The right-hand side operand. + + Returns: + The product of the two values. + """ return decimo.bigint10.arithmetics.multiply(self, other) @always_inline def __floordiv__(self, other: Self) raises -> Self: + """Divides two values using floor division. + + Args: + other: The right-hand side operand. + + Returns: + The floor division quotient. + """ try: return decimo.bigint10.arithmetics.floor_divide(self, other) except e: @@ -547,6 +631,14 @@ struct BigInt10( @always_inline def __mod__(self, other: Self) raises -> Self: + """Returns the remainder of division. + + Args: + other: The right-hand side operand. + + Returns: + The remainder of the floor division. + """ try: return decimo.bigint10.arithmetics.floor_modulo(self, other) except e: @@ -561,6 +653,14 @@ struct BigInt10( @always_inline def __pow__(self, exponent: Self) raises -> Self: + """Raises to a power. + + Args: + exponent: The exponent. + + Returns: + The result of raising to the given power. + """ return self.power(exponent) # ===------------------------------------------------------------------=== # @@ -571,26 +671,74 @@ struct BigInt10( @always_inline def __radd__(self, other: Self) -> Self: + """Adds two values (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The sum of the two values. + """ return decimo.bigint10.arithmetics.add(self, other) @always_inline def __rsub__(self, other: Self) -> Self: + """Subtracts two values (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The difference of the two values. + """ return decimo.bigint10.arithmetics.subtract(other, self) @always_inline def __rmul__(self, other: Self) -> Self: + """Multiplies two values (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The product of the two values. + """ return decimo.bigint10.arithmetics.multiply(self, other) @always_inline def __rfloordiv__(self, other: Self) raises -> Self: + """Divides two values using floor division (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The floor division quotient. + """ return decimo.bigint10.arithmetics.floor_divide(other, self) @always_inline def __rmod__(self, other: Self) raises -> Self: + """Returns the remainder of division (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The remainder of the floor division. + """ return decimo.bigint10.arithmetics.floor_modulo(other, self) @always_inline def __rpow__(self, base: Self) raises -> Self: + """Raises to a power (reflected). + + Args: + base: The base to raise to this power. + + Returns: + The result of raising to the given power. + """ return base.power(self) # ===------------------------------------------------------------------=== # @@ -602,10 +750,20 @@ struct BigInt10( @always_inline def __iadd__(mut self, other: Self): + """Adds in place. + + Args: + other: The right-hand side operand. + """ decimo.bigint10.arithmetics.add_inplace(self, other) @always_inline def __iadd__(mut self, other: Int): + """Adds in place. + + Args: + other: The right-hand side operand. + """ # Optimize the case `i += 1` if (self >= 0) and (other >= 0) and (other <= 999_999_999): decimo.biguint.arithmetics.add_inplace_by_uint32( @@ -616,18 +774,38 @@ struct BigInt10( @always_inline def __isub__(mut self, other: Self): + """Subtracts in place. + + Args: + other: The right-hand side operand. + """ self = decimo.bigint10.arithmetics.subtract(self, other) @always_inline def __imul__(mut self, other: Self): + """Multiplies in place. + + Args: + other: The right-hand side operand. + """ self = decimo.bigint10.arithmetics.multiply(self, other) @always_inline def __ifloordiv__(mut self, other: Self) raises: + """Divides in place using floor division. + + Args: + other: The right-hand side operand. + """ self = decimo.bigint10.arithmetics.floor_divide(self, other) @always_inline def __imod__(mut self, other: Self) raises: + """Computes the remainder in place. + + Args: + other: The right-hand side operand. + """ self = decimo.bigint10.arithmetics.floor_modulo(self, other) # ===------------------------------------------------------------------=== # @@ -637,64 +815,148 @@ struct BigInt10( @always_inline def __gt__(self, other: Self) -> Bool: - """Returns True if self > other.""" + """Checks if this value is greater than `other`. + + Args: + other: The value to compare against. + + Returns: + `True` if `self > other`, `False` otherwise. + """ return decimo.bigint10.comparison.greater(self, other) @always_inline def __gt__(self, other: Int) -> Bool: - """Returns True if self > other.""" + """Checks if this value is greater than `other`. + + Args: + other: The value to compare against. + + Returns: + `True` if `self > other`, `False` otherwise. + """ return decimo.bigint10.comparison.greater(self, Self.from_int(other)) @always_inline def __ge__(self, other: Self) -> Bool: - """Returns True if self >= other.""" + """Checks if this value is greater than or equal to `other`. + + Args: + other: The value to compare against. + + Returns: + `True` if `self >= other`, `False` otherwise. + """ return decimo.bigint10.comparison.greater_equal(self, other) @always_inline def __ge__(self, other: Int) -> Bool: - """Returns True if self >= other.""" + """Checks if this value is greater than or equal to `other`. + + Args: + other: The value to compare against. + + Returns: + `True` if `self >= other`, `False` otherwise. + """ return decimo.bigint10.comparison.greater_equal( self, Self.from_int(other) ) @always_inline def __lt__(self, other: Self) -> Bool: - """Returns True if self < other.""" + """Checks if this value is less than `other`. + + Args: + other: The value to compare against. + + Returns: + `True` if `self < other`, `False` otherwise. + """ return decimo.bigint10.comparison.less(self, other) @always_inline def __lt__(self, other: Int) -> Bool: - """Returns True if self < other.""" + """Checks if this value is less than `other`. + + Args: + other: The value to compare against. + + Returns: + `True` if `self < other`, `False` otherwise. + """ return decimo.bigint10.comparison.less(self, Self.from_int(other)) @always_inline def __le__(self, other: Self) -> Bool: - """Returns True if self <= other.""" + """Checks if this value is less than or equal to `other`. + + Args: + other: The value to compare against. + + Returns: + `True` if `self <= other`, `False` otherwise. + """ return decimo.bigint10.comparison.less_equal(self, other) @always_inline def __le__(self, other: Int) -> Bool: - """Returns True if self <= other.""" + """Checks if this value is less than or equal to `other`. + + Args: + other: The value to compare against. + + Returns: + `True` if `self <= other`, `False` otherwise. + """ return decimo.bigint10.comparison.less_equal(self, Self.from_int(other)) @always_inline def __eq__(self, other: Self) -> Bool: - """Returns True if self == other.""" + """Checks if this value is equal to `other`. + + Args: + other: The value to compare against. + + Returns: + `True` if `self == other`, `False` otherwise. + """ return decimo.bigint10.comparison.equal(self, other) @always_inline def __eq__(self, other: Int) -> Bool: - """Returns True if self == other.""" + """Checks if this value is equal to `other`. + + Args: + other: The value to compare against. + + Returns: + `True` if `self == other`, `False` otherwise. + """ return decimo.bigint10.comparison.equal(self, Self.from_int(other)) @always_inline def __ne__(self, other: Self) -> Bool: - """Returns True if self != other.""" + """Checks if this value is not equal to `other`. + + Args: + other: The value to compare against. + + Returns: + `True` if `self != other`, `False` otherwise. + """ return decimo.bigint10.comparison.not_equal(self, other) @always_inline def __ne__(self, other: Int) -> Bool: - """Returns True if self != other.""" + """Checks if this value is not equal to `other`. + + Args: + other: The value to compare against. + + Returns: + `True` if `self != other`, `False` otherwise. + """ return decimo.bigint10.comparison.not_equal(self, Self.from_int(other)) # ===------------------------------------------------------------------=== # @@ -702,7 +964,14 @@ struct BigInt10( # ===------------------------------------------------------------------=== # def __merge_with__[other_type: type_of(BigDecimal)](self) -> BigDecimal: - "Merges this BigInt10 with a BigDecimal into a BigDecimal." + """Merges this BigInt10 with a BigDecimal into a BigDecimal. + + Parameters: + other_type: The target type. + + Returns: + A BigDecimal value. + """ return BigDecimal(self) # ===------------------------------------------------------------------=== # @@ -713,6 +982,12 @@ struct BigInt10( def floor_divide(self, other: Self) raises -> Self: """Performs a floor division of two BigInts. See `floor_divide()` for more information. + + Args: + other: The divisor. + + Returns: + The floor division quotient. """ return decimo.bigint10.arithmetics.floor_divide(self, other) @@ -720,6 +995,12 @@ struct BigInt10( def truncate_divide(self, other: Self) raises -> Self: """Performs a truncated division of two BigInts. See `truncate_divide()` for more information. + + Args: + other: The divisor. + + Returns: + The truncated division quotient. """ return decimo.bigint10.arithmetics.truncate_divide(self, other) @@ -727,6 +1008,12 @@ struct BigInt10( def floor_modulo(self, other: Self) raises -> Self: """Performs a floor modulo of two BigInts. See `floor_modulo()` for more information. + + Args: + other: The divisor. + + Returns: + The floor division remainder. """ return decimo.bigint10.arithmetics.floor_modulo(self, other) @@ -734,12 +1021,24 @@ struct BigInt10( def truncate_modulo(self, other: Self) raises -> Self: """Performs a truncated modulo of two BigInts. See `truncate_modulo()` for more information. + + Args: + other: The divisor. + + Returns: + The truncated division remainder. """ return decimo.bigint10.arithmetics.truncate_modulo(self, other) def power(self, exponent: Int) raises -> Self: """Raises the BigInt10 to the power of an integer exponent. See `power()` for more information. + + Args: + exponent: The exponent. + + Returns: + The result of raising to the given power. """ var magnitude = self.magnitude.power(exponent) var sign = False @@ -750,6 +1049,12 @@ struct BigInt10( def power(self, exponent: Self) raises -> Self: """Raises the BigInt10 to the power of another BigInt10. See `power()` for more information. + + Args: + exponent: The exponent. + + Returns: + The result of raising to the given power. """ if exponent > Self(BigUInt(raw_words=[0, 1]), sign=False): raise Error("Error in `BigUInt.power()`: The exponent is too large") @@ -760,6 +1065,12 @@ struct BigInt10( def compare_magnitudes(self, other: Self) -> Int8: """Compares the magnitudes of two BigInts. See `compare_magnitudes()` for more information. + + Args: + other: The value to compare against. + + Returns: + 1 if `self` magnitude is greater, -1 if less, 0 if equal. """ return decimo.bigint10.comparison.compare_magnitudes(self, other) @@ -767,6 +1078,12 @@ struct BigInt10( def compare(self, other: Self) -> Int8: """Compares two BigInts. See `compare()` for more information. + + Args: + other: The value to compare against. + + Returns: + 1 if `self` is greater, -1 if less, 0 if equal. """ return decimo.bigint10.comparison.compare(self, other) @@ -776,22 +1093,38 @@ struct BigInt10( @always_inline def is_zero(self) -> Bool: - """Returns True if this BigInt10 represents zero.""" + """Returns True if this BigInt10 represents zero. + + Returns: + `True` if zero, `False` otherwise. + """ return self.magnitude.is_zero() @always_inline def is_one_or_minus_one(self) -> Bool: - """Returns True if this BigInt10 represents one or negative one.""" + """Returns True if this BigInt10 represents one or negative one. + + Returns: + `True` if the value is 1 or -1, `False` otherwise. + """ return self.magnitude.is_one() @always_inline def is_negative(self) -> Bool: - """Returns True if this BigInt10 is negative.""" + """Returns True if this BigInt10 is negative. + + Returns: + `True` if negative, `False` otherwise. + """ return self.sign @always_inline def number_of_words(self) -> Int: - """Returns the number of words in the BigInt10.""" + """Returns the number of words in the BigInt10. + + Returns: + The number of internal words. + """ return len(self.magnitude.words) # ===------------------------------------------------------------------=== # @@ -799,7 +1132,11 @@ struct BigInt10( # ===------------------------------------------------------------------=== # def internal_representation(self) raises -> String: - """Returns the internal representation details as a String.""" + """Returns the internal representation details as a String. + + Returns: + A formatted string showing the internal representation. + """ # Collect all labels to find max width var max_label_len = len("number:") for i in range(len(self.magnitude.words)): diff --git a/src/decimo/biguint/arithmetics.mojo b/src/decimo/biguint/arithmetics.mojo index 46a7face..4fba0026 100644 --- a/src/decimo/biguint/arithmetics.mojo +++ b/src/decimo/biguint/arithmetics.mojo @@ -453,7 +453,12 @@ def add_inplace_by_slice( def add_inplace_by_uint32(mut x: BigUInt, y: UInt32) -> None: - """Increments a BigUInt number by a UInt32 value.""" + """Increments a BigUInt number by a UInt32 value. + + Args: + x: The `BigUInt` number to increment. + y: The `UInt32` value to add. + """ var carry: UInt32 = y for i in range(len(x.words)): x.words[i] += carry @@ -679,7 +684,12 @@ def subtract_simd(x: BigUInt, y: BigUInt) raises -> BigUInt: def subtract_inplace(mut x: BigUInt, y: BigUInt) raises -> None: - """Subtracts y from x in place.""" + """Subtracts y from x in place. + + Args: + x: The `BigUInt` minuend, modified in place. + y: The `BigUInt` subtrahend. + """ # If the subtrahend is zero, return the minuend if y.is_zero(): @@ -740,6 +750,10 @@ def subtract_inplace_no_check(mut x: BigUInt, y: BigUInt) -> None: This function assumes that x >= y, and it does not check for underflow. It is the caller's responsibility to ensure that x is greater than or equal to y before calling this function. + + Args: + x: The `BigUInt` minuend, modified in place. + y: The `BigUInt` subtrahend. """ # If the subtrahend is zero, return the minuend @@ -954,6 +968,9 @@ def multiply_slices_school( y: The second BigUInt operand (multiplier). bounds_x: A tuple containing the start and end indices of the slice in x. bounds_y: A tuple containing the start and end indices of the slice in y. + + Returns: + The product of the two BigUInt slices. """ n_words_x_slice = bounds_x[1] - bounds_x[0] @@ -1797,6 +1814,9 @@ def multiply_by_power_of_billion(x: BigUInt, n: Int) -> BigUInt: In non-debug model, if n is less than or equal to 0, the function returns x unchanged. In debug mode, it asserts that n is non-negative. + + Returns: + A new `BigUInt` containing the result of the multiplication. """ debug_assert[assert_mode="none"]( n >= 0, @@ -1878,6 +1898,9 @@ def exact_divide_by_2_inplace(mut x: BigUInt): The caller must ensure that x is even (divisible by 2). Uses base-10^9 long division from MSB to LSB. + + Args: + x: The `BigUInt` value to divide, modified in place. """ var carry: UInt32 = 0 for i in range(len(x.words) - 1, -1, -1): @@ -1894,6 +1917,9 @@ def exact_divide_by_3_inplace(mut x: BigUInt): The caller must ensure that x is divisible by 3. Uses base-10^9 long division from MSB to LSB. + + Args: + x: The `BigUInt` value to divide, modified in place. """ var carry: UInt32 = 0 for i in range(len(x.words) - 1, -1, -1): @@ -2238,6 +2264,9 @@ def floor_divide_by_uint32(x: BigUInt, y: UInt32) -> BigUInt: This function is used internally for division by single word divisors. It is not intended for public use. You need to ensure that y is non-zero. + + Returns: + The quotient of x divided by y. """ debug_assert[assert_mode="none"]( y != 0, "biguint.arithmetics.floor_divide_by_uint32(): Division by zero" @@ -2304,8 +2333,11 @@ def floor_divide_by_uint64(x: BigUInt, y: UInt64) -> BigUInt: """Divides a BigUInt by UInt64. Args: - x: The BigUInt value to divide by the divisor. - y: The UInt64 divisor. Must be smaller than 10^18. + x: The `BigUInt` dividend. + y: The `UInt64` divisor. Must be smaller than 10^18. + + Returns: + The quotient of x divided by y. """ debug_assert[assert_mode="none"]( y != 0, @@ -2379,8 +2411,11 @@ def floor_divide_by_uint128(x: BigUInt, y: UInt128) -> BigUInt: """Divides a BigUInt by UInt128. Args: - x: The BigUInt value to divide by the divisor. - y: The UInt128 divisor. Must be smaller than 10^36. + x: The `BigUInt` dividend. + y: The `UInt128` divisor. Must be smaller than 10^36. + + Returns: + The quotient of x divided by y. """ debug_assert[assert_mode="none"]( y != 0, @@ -2630,6 +2665,9 @@ def floor_divide_burnikel_ziegler( cut_off: The cutoff value for the number of words in the divisor to use the schoolbook division algorithm. It also determines the size of the blocks used in the recursive division algorithm. + + Returns: + The quotient of `a` divided by `b`. """ var BLOCK_SIZE_OF_WORDS = cut_off @@ -3179,6 +3217,13 @@ def truncate_divide(x1: BigUInt, x2: BigUInt) raises -> BigUInt: """Returns the quotient of two BigUInt numbers, truncating toward zero. It is equal to floored division for unsigned numbers. See `floor_divide` for more details. + + Args: + x1: The dividend. + x2: The divisor. + + Returns: + The quotient of `x1` divided by `x2`. """ return floor_divide(x1, x2) @@ -3423,6 +3468,9 @@ def normalize_carries_lt_2_bases(mut x: BigUInt): a situation where some words are larger than BASE. This function normalizes the carries, ensuring that all words are within the valid range. It modifies the input BigUInt in-place. + + Args: + x: The `BigUInt` to normalize, modified in place. """ # Yuhao ZHU: @@ -3459,6 +3507,9 @@ def normalize_carries_lt_4_bases(mut x: BigUInt): a situation where some words are ge than BASE but le BASE * 4 - 4. This function normalizes the carries, ensuring that all words are within the valid range. It modifies the input BigUInt in-place. + + Args: + x: The `BigUInt` to normalize, modified in place. """ # Yuhao ZHU: @@ -3536,6 +3587,9 @@ def normalize_borrows(mut x: BigUInt): a situation where some words are **underflowed**. We can take advantage of the overflowed values of the words to normalize the borrows, ensuring that all words are within the valid range. + + Args: + x: The `BigUInt` to normalize, modified in place. """ comptime NEG_BASE_MAX = UInt32(3294967297) # UInt32(0) - BigUInt.BASE_MAX @@ -3664,7 +3718,15 @@ def calculate_ndigits_for_normalization(msw: UInt32) -> Int: def to_uint64_with_2_words(a: BigUInt, bounds_x: Tuple[Int, Int]) -> UInt64: - """Convert two words at given index of the BigUInt to UInt64.""" + """Convert two words at given index of the BigUInt to UInt64. + + Args: + a: The `BigUInt` containing the words to convert. + bounds_x: A tuple of (start, end) indices specifying the word slice. + + Returns: + The `UInt64` representation of the specified words. + """ var n_words = bounds_x[1] - bounds_x[0] if n_words == 1: return ( @@ -3678,7 +3740,15 @@ def to_uint64_with_2_words(a: BigUInt, bounds_x: Tuple[Int, Int]) -> UInt64: def to_uint128_with_2_words(a: BigUInt, bounds_x: Tuple[Int, Int]) -> UInt128: - """Convert two words at given index of the BigUInt to UInt128.""" + """Convert two words at given index of the BigUInt to UInt128. + + Args: + a: The `BigUInt` containing the words to convert. + bounds_x: A tuple of (start, end) indices specifying the word slice. + + Returns: + The `UInt128` representation of the specified words. + """ var n_words = bounds_x[1] - bounds_x[0] if n_words == 1: return ( @@ -3696,7 +3766,15 @@ def to_uint128_with_2_words(a: BigUInt, bounds_x: Tuple[Int, Int]) -> UInt128: def to_uint128_with_4_words(a: BigUInt, bounds_x: Tuple[Int, Int]) -> UInt128: - """Convert four words at given index of the BigUInt to UInt128.""" + """Convert four words at given index of the BigUInt to UInt128. + + Args: + a: The `BigUInt` containing the words to convert. + bounds_x: A tuple of (start, end) indices specifying the word slice. + + Returns: + The `UInt128` representation of the specified words. + """ var n_words = bounds_x[1] - bounds_x[0] if n_words == 1: return ( diff --git a/src/decimo/biguint/biguint.mojo b/src/decimo/biguint/biguint.mojo index bac17abe..dfdd0aef 100644 --- a/src/decimo/biguint/biguint.mojo +++ b/src/decimo/biguint/biguint.mojo @@ -39,6 +39,7 @@ import decimo.str # Type aliases comptime BUInt = BigUInt +"""A shorthand alias for `BigUInt`.""" struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): @@ -84,28 +85,47 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): """The width of the SIMD vector used for arithmetic operations (128-bit).""" comptime ZERO = Self.zero() + """A `BigUInt` constant representing zero.""" comptime ONE = Self.one() + """A `BigUInt` constant representing one.""" comptime MAX_UINT64 = Self(raw_words=[709551615, 446744073, 18]) + """A `BigUInt` constant representing the maximum value of `UInt64`.""" comptime MAX_UINT128 = Self( raw_words=[768211455, 374607431, 938463463, 282366920, 340] ) + """A `BigUInt` constant representing the maximum value of `UInt128`.""" @always_inline @staticmethod def zero() -> Self: - """Returns a BigUInt with value 0.""" + """Returns a BigUInt with value 0. + + Returns: + A `BigUInt` with value 0. + """ return Self() @always_inline @staticmethod def one() -> Self: - """Returns a BigUInt with value 1.""" + """Returns a BigUInt with value 1. + + Returns: + A `BigUInt` with value 1. + """ return Self(raw_words=[UInt32(1)]) @staticmethod @always_inline def power_of_10(exponent: Int) raises -> Self: - """Calculates 10^exponent efficiently.""" + """Calculates 10^exponent efficiently. + + Args: + exponent: The power of 10 to compute. + + Returns: + A `BigUInt` representing 10 raised to the power of `exponent`. + """ return decimo.biguint.arithmetics.power_of_10(exponent) # ===------------------------------------------------------------------=== # @@ -218,9 +238,12 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): # TODO: If Mojo makes Int type an alias of SIMD[DType.index, 1], # we can remove this method. def __init__(out self, value: Int) raises: - """Initializes a BigUInt from an Int. + """Initializes a BigUInt from an `Int`. See `from_int()` for more information. + Args: + value: The integer to initialize the `BigUInt` from. + Raises: Error: Calling `BigUInt.from_int()`. """ @@ -240,6 +263,9 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): def __init__(out self, value: Scalar): """Initializes a BigUInt from an unsigned integral scalar. See `from_unsigned_integral_scalar()` for more information. + + Args: + value: The unsigned integral scalar to initialize the `BigUInt` from. """ self = Self.from_unsigned_integral_scalar(value) @@ -363,6 +389,9 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): BigUInt.from_words(123456789, 987654321) # 987654321_123456789 ``` End of examples. + + Returns: + The `BigUInt` representation of the given words. """ var list_of_words = List[UInt32](capacity=len(words)) @@ -392,11 +421,14 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): """Initializes a BigUInt from a BigUInt slice. Args: - value: The BigUInt to copy from. + value: The `BigUInt` to copy from. bounds: A tuple of two integers representing the bounds for the words to copy. The first integer is the start index (inclusive), and the second integer is the end index (exclusive). + + Returns: + A new `BigUInt` containing the specified slice of words. """ # Safty checks on bounds var start_index: Int @@ -470,7 +502,13 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): @staticmethod def from_uint32_unsafe(unsafe_value: UInt32) -> Self: - """Creates a BigUInt from an `UInt32` object without checking the value. + """Creates a BigUInt from a `UInt32` object without checking the value. + + Args: + unsafe_value: The `UInt32` value to wrap directly as a single word. + + Returns: + A single-word `BigUInt` containing the given value. """ return Self(raw_words=[unsafe_value]) @@ -503,6 +541,9 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): - UInt32: Check whether one word or two words are needed. - UInt64, UInt128, etc: repeatedly divide by 1_000_000_000. - UIndex (UInt): repeatedly divide by 1_000_000_000. + + Parameters: + dtype: The scalar data type, must be integral and unsigned. """ # Only allow unsigned integral types @@ -560,6 +601,9 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): Returns: The BigUInt representation of the Scalar value. + + Parameters: + dtype: The scalar data type, must be integral. """ comptime assert dtype.is_integral(), "dtype must be integral." @@ -770,7 +814,14 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): ) def write_repr_to[W: Writer](self, mut writer: W): - """Writes the debug representation to a writer.""" + """Writes the debug representation to a writer. + + Parameters: + W: A type conforming to the `Writer` interface. + + Args: + writer: The writer instance. + """ writer.write('BigUInt("', self.to_string(), '")') # ===------------------------------------------------------------------=== # @@ -780,6 +831,12 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): def write_to[W: Writer](self, mut writer: W): """Writes the BigUInt to a writer. This implement the `write` method of the `Writer` trait. + + Parameters: + W: A type conforming to the `Writer` interface. + + Args: + writer: The writer instance. """ writer.write(self.to_string()) @@ -864,6 +921,9 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): Notes: This method quickly convert BigUInt with 2 words into UInt64. + + Returns: + The `UInt64` representation of the first two words. """ if len(self.words) == 1: return self.words.unsafe_ptr().load[width=1]().cast[DType.uint64]() @@ -942,6 +1002,9 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): Notes: This method quickly convert BigUInt with 4 words into UInt128. + + Returns: + The `UInt128` representation of the first four words. """ if len(self.words) == 1: @@ -1047,6 +1110,9 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): def __abs__(self) -> Self: """Returns the absolute value of this number. See `absolute()` for more information. + + Returns: + The absolute value. """ return decimo.biguint.arithmetics.absolute(self) @@ -1054,12 +1120,21 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): def __neg__(self) raises -> Self: """Returns the negation of this number. See `negative()` for more information. + + Returns: + The negated value. """ return decimo.biguint.arithmetics.negative(self) @always_inline def __rshift__(self, shift_amount: Int) -> Self: """Returns the result of floored divison by 2 to the power of `shift_amount`. + + Args: + shift_amount: The number of bit positions to shift right. + + Returns: + The floor-divided value. """ var result = self.copy() for _ in range(shift_amount): @@ -1074,10 +1149,26 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): @always_inline def __add__(self, other: Self) -> Self: + """Adds two values. + + Args: + other: The right-hand side operand. + + Returns: + The sum. + """ return decimo.biguint.arithmetics.add(self, other) @always_inline def __sub__(self, other: Self) raises -> Self: + """Subtracts two values. + + Args: + other: The right-hand side operand. + + Returns: + The difference. + """ try: return decimo.biguint.arithmetics.subtract(self, other) except e: @@ -1092,10 +1183,26 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): @always_inline def __mul__(self, other: Self) -> Self: + """Multiplies two values. + + Args: + other: The right-hand side operand. + + Returns: + The product. + """ return decimo.biguint.arithmetics.multiply(self, other) @always_inline def __floordiv__(self, other: Self) raises -> Self: + """Divides two values using floor division. + + Args: + other: The right-hand side operand. + + Returns: + The quotient. + """ try: return decimo.biguint.arithmetics.floor_divide(self, other) except e: @@ -1110,7 +1217,14 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): @always_inline def __ceildiv__(self, other: Self) raises -> Self: - """Returns the result of ceiling division.""" + """Returns the result of ceiling division. + + Args: + other: The right-hand side operand. + + Returns: + The quotient rounded up. + """ try: return decimo.biguint.arithmetics.ceil_divide(self, other) except e: @@ -1125,6 +1239,14 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): @always_inline def __mod__(self, other: Self) raises -> Self: + """Returns the remainder of division. + + Args: + other: The right-hand side operand. + + Returns: + The remainder. + """ try: return decimo.biguint.arithmetics.floor_modulo(self, other) except e: @@ -1139,6 +1261,14 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): @always_inline def __divmod__(self, other: Self) raises -> Tuple[Self, Self]: + """Returns the quotient and remainder of division. + + Args: + other: The right-hand side operand. + + Returns: + A tuple of (quotient, remainder). + """ try: return decimo.biguint.arithmetics.floor_divide_modulo(self, other) except e: @@ -1153,6 +1283,14 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): @always_inline def __pow__(self, exponent: Self) raises -> Self: + """Raises to a power. + + Args: + exponent: The exponent to raise this number to. + + Returns: + The power `self` raised to `exponent`. + """ try: return self.power(exponent) except e: @@ -1167,6 +1305,14 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): @always_inline def __pow__(self, exponent: Int) raises -> Self: + """Raises to a power. + + Args: + exponent: The exponent to raise this number to. + + Returns: + The power `self` raised to `exponent`. + """ try: return self.power(exponent) except e: @@ -1187,30 +1333,86 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): @always_inline def __radd__(self, other: Self) raises -> Self: + """Adds two values (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The sum. + """ return decimo.biguint.arithmetics.add(self, other) @always_inline def __rsub__(self, other: Self) raises -> Self: + """Subtracts two values (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The difference. + """ return decimo.biguint.arithmetics.subtract(other, self) @always_inline def __rmul__(self, other: Self) raises -> Self: + """Multiplies two values (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The product. + """ return decimo.biguint.arithmetics.multiply(self, other) @always_inline def __rfloordiv__(self, other: Self) raises -> Self: + """Divides two values using floor division (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The quotient. + """ return decimo.biguint.arithmetics.floor_divide(other, self) @always_inline def __rmod__(self, other: Self) raises -> Self: + """Returns the remainder of division (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The remainder. + """ return decimo.biguint.arithmetics.floor_modulo(other, self) @always_inline def __rdivmod__(self, other: Self) raises -> Tuple[Self, Self]: + """Returns the quotient and remainder of division (reflected). + + Args: + other: The left-hand side operand. + + Returns: + A tuple of (quotient, remainder). + """ return decimo.biguint.arithmetics.floor_divide_modulo(other, self) @always_inline def __rpow__(self, base: Self) raises -> Self: + """Raises to a power (reflected). + + Args: + base: The base to raise to the power of `self`. + + Returns: + The power `base` raised to `self`. + """ return base.power(self) # ===------------------------------------------------------------------=== # @@ -1224,6 +1426,9 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): def __iadd__(mut self, other: Self): """Adds `other` to `self` in place. See `biguint.arithmetics.add_inplace()` for more information. + + Args: + other: The operand to add. """ decimo.biguint.arithmetics.add_inplace(self, other) @@ -1231,19 +1436,37 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): def __isub__(mut self, other: Self) raises: """Subtracts `other` from `self` in place. See `biguint.arithmetics.subtract_inplace()` for more information. + + Args: + other: The operand to subtract. """ decimo.biguint.arithmetics.subtract_inplace(self, other) @always_inline def __imul__(mut self, other: Self) raises: + """Multiplies in place. + + Args: + other: The operand to multiply by. + """ self = decimo.biguint.arithmetics.multiply(self, other) @always_inline def __ifloordiv__(mut self, other: Self) raises: + """Divides in place using floor division. + + Args: + other: The divisor. + """ self = decimo.biguint.arithmetics.floor_divide(self, other) @always_inline def __imod__(mut self, other: Self) raises: + """Computes the remainder in place. + + Args: + other: The divisor. + """ self = decimo.biguint.arithmetics.floor_modulo(self, other) # ===------------------------------------------------------------------=== # @@ -1253,32 +1476,74 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): @always_inline def __gt__(self, other: Self) -> Bool: - """Returns True if self > other.""" + """Returns True if self > other. + + Args: + other: The value to compare against. + + Returns: + `True` if `self` is greater than `other`, `False` otherwise. + """ return decimo.biguint.comparison.greater(self, other) @always_inline def __ge__(self, other: Self) -> Bool: - """Returns True if self >= other.""" + """Returns True if self >= other. + + Args: + other: The value to compare against. + + Returns: + `True` if `self` is greater than or equal to `other`, `False` otherwise. + """ return decimo.biguint.comparison.greater_equal(self, other) @always_inline def __lt__(self, other: Self) -> Bool: - """Returns True if self < other.""" + """Returns True if self < other. + + Args: + other: The value to compare against. + + Returns: + `True` if `self` is less than `other`, `False` otherwise. + """ return decimo.biguint.comparison.less(self, other) @always_inline def __le__(self, other: Self) -> Bool: - """Returns True if self <= other.""" + """Returns True if self <= other. + + Args: + other: The value to compare against. + + Returns: + `True` if `self` is less than or equal to `other`, `False` otherwise. + """ return decimo.biguint.comparison.less_equal(self, other) @always_inline def __eq__(self, other: Self) -> Bool: - """Returns True if self == other.""" + """Returns True if self == other. + + Args: + other: The value to compare against. + + Returns: + `True` if `self` equals `other`, `False` otherwise. + """ return decimo.biguint.comparison.equal(self, other) @always_inline def __ne__(self, other: Self) -> Bool: - """Returns True if self != other.""" + """Returns True if self != other. + + Args: + other: The value to compare against. + + Returns: + `True` if `self` does not equal `other`, `False` otherwise. + """ return decimo.biguint.comparison.not_equal(self, other) # ===------------------------------------------------------------------=== # @@ -1286,11 +1551,25 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): # ===------------------------------------------------------------------=== # def __merge_with__[other_type: type_of(BigInt10)](self) -> BigInt10: - "Merges this BigUInt with a BigInt10 into a BigInt10." + """Merges this BigUInt with a BigInt10 into a BigInt10. + + Parameters: + other_type: The target type. + + Returns: + A BigInt10 value. + """ return BigInt10(self) def __merge_with__[other_type: type_of(BigDecimal)](self) -> BigDecimal: - "Merges this BigUInt with a BigDecimal into a BigDecimal." + """Merges this BigUInt with a BigDecimal into a BigDecimal. + + Parameters: + other_type: The target type. + + Returns: + A BigDecimal value. + """ return BigDecimal(self) # ===------------------------------------------------------------------=== # @@ -1302,6 +1581,9 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): """Adds `other` to this number in place. It is equal to `self += other`. See `add_inplace()` for more information. + + Args: + other: The operand to add. """ decimo.biguint.arithmetics.add_inplace(self, other) @@ -1310,6 +1592,12 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): """Returns the result of floor dividing this number by `other`. It is equal to `self // other`. See `floor_divide()` for more information. + + Args: + other: The divisor. + + Returns: + The quotient. """ return decimo.biguint.arithmetics.floor_divide(self, other) @@ -1318,6 +1606,12 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): """Returns the result of truncate dividing this number by `other`. It is equal to `self // other`. See `truncate_divide()` for more information. + + Args: + other: The divisor. + + Returns: + The quotient. """ return decimo.biguint.arithmetics.truncate_divide(self, other) @@ -1325,6 +1619,12 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): def ceil_divide(self, other: Self) raises -> Self: """Returns the result of ceil dividing this number by `other`. See `ceil_divide()` for more information. + + Args: + other: The divisor. + + Returns: + The quotient rounded up. """ return decimo.biguint.arithmetics.ceil_divide(self, other) @@ -1332,6 +1632,12 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): def floor_modulo(self, other: Self) raises -> Self: """Returns the result of floor modulo this number by `other`. See `floor_modulo()` for more information. + + Args: + other: The divisor. + + Returns: + The remainder. """ return decimo.biguint.arithmetics.floor_modulo(self, other) @@ -1339,6 +1645,12 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): def truncate_modulo(self, other: Self) raises -> Self: """Returns the result of truncate modulo this number by `other`. See `truncate_modulo()` for more information. + + Args: + other: The divisor. + + Returns: + The remainder. """ return decimo.biguint.arithmetics.truncate_modulo(self, other) @@ -1346,6 +1658,12 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): def ceil_modulo(self, other: Self) raises -> Self: """Returns the result of ceil modulo this number by `other`. See `ceil_modulo()` for more information. + + Args: + other: The divisor. + + Returns: + The remainder. """ return decimo.biguint.arithmetics.ceil_modulo(self, other) @@ -1353,6 +1671,12 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): def divmod(self, other: Self) raises -> Tuple[Self, Self]: """Returns the result of divmod this number by `other`. See `divmod()` for more information. + + Args: + other: The divisor. + + Returns: + A tuple of (quotient, remainder). """ return decimo.biguint.arithmetics.floor_divide_modulo(self, other) @@ -1367,6 +1691,12 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): def multiply_by_power_of_ten(self, n: Int) -> Self: """Returns the result of multiplying this number by 10^n (n>=0). See `multiply_by_power_of_ten()` for more information. + + Args: + n: The power of 10 to multiply by. + + Returns: + The product of this number and 10^n. """ return decimo.biguint.arithmetics.multiply_by_power_of_ten(self, n) @@ -1374,6 +1704,9 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): def multiply_inplace_by_power_of_ten(mut self, n: Int): """Multiplies this number in-place by 10^n (n>=0). See `multiply_inplace_by_power_of_ten()` for more information. + + Args: + n: The power of 10 to multiply by. """ decimo.biguint.arithmetics.multiply_inplace_by_power_of_ten(self, n) @@ -1382,6 +1715,12 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): """Returns the result of floored dividing this number by 10^n (n>=0). It is equal to removing the last n digits of the number. See `floor_divide_by_power_of_ten()` for more information. + + Args: + n: The power of 10 to divide by. + + Returns: + The quotient after removing the last `n` digits. """ return decimo.biguint.arithmetics.floor_divide_by_power_of_ten(self, n) @@ -1402,8 +1741,7 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): exponent: The exponent to raise the number to. Returns: - ValueError: If the exponent is negative. - ValueError: If the exponent is too large. + A `BigUInt` representing `self` raised to the power of `exponent`. Raises: Error: If the exponent is negative. @@ -1511,6 +1849,12 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): def compare(self, other: Self) -> Int8: """Compares the magnitudes of two BigUInts. See `compare()` for more information. + + Args: + other: The value to compare against. + + Returns: + A positive value if `self > other`, 0 if equal, or a negative value if `self < other`. """ return decimo.biguint.comparison.compare(self, other) @@ -1519,7 +1863,11 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): # ===------------------------------------------------------------------=== # def internal_representation(self) -> String: - """Returns the internal representation details as a String.""" + """Returns the internal representation details as a String. + + Returns: + A formatted string showing the number and its individual words. + """ # Collect all labels to find max width var max_label_len = len("number:") for i in range(len(self.words)): @@ -1561,7 +1909,11 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): @always_inline def is_zero(self) -> Bool: - """Returns True if this BigUInt represents zero.""" + """Returns True if this BigUInt represents zero. + + Returns: + `True` if the value is zero, `False` otherwise. + """ # Yuhao ZHU: # BigUInt are desgined to have no leading zero words, # so that we only need to check words[0] for zero. @@ -1603,7 +1955,11 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): @always_inline def is_one(self) -> Bool: - """Returns True if this BigUInt represents one.""" + """Returns True if this BigUInt represents one. + + Returns: + `True` if the value is one, `False` otherwise. + """ if self.words[0] != 1: # Least significant word is not 1 return False @@ -1621,7 +1977,11 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): @always_inline def is_two(self) -> Bool: - """Returns True if this BigUInt represents two.""" + """Returns True if this BigUInt represents two. + + Returns: + `True` if the value is two, `False` otherwise. + """ if len(self.words) != 2: return False for i in self.words[1:]: @@ -1631,7 +1991,11 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): @always_inline def is_power_of_10(x: BigUInt) -> Bool: - """Check if x is a power of 10.""" + """Check if x is a power of 10. + + Returns: + `True` if the value is a power of 10, `False` otherwise. + """ for i in range(len(x.words) - 1): if x.words[i] != 0: return False @@ -1652,12 +2016,20 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): @always_inline def is_unitialized(self) -> Bool: - """Returns True if the BigUInt is uninitialized.""" + """Returns True if the BigUInt is uninitialized. + + Returns: + `True` if the words list is empty, `False` otherwise. + """ return len(self.words) == 0 @always_inline def is_uint64_overflow(self) -> Bool: - """Returns True if the BigUInt larger than UInt64.MAX.""" + """Returns True if the BigUInt larger than UInt64.MAX. + + Returns: + `True` if the value exceeds `UInt64.MAX`, `False` otherwise. + """ # UInt64.MAX: 18_446_744_073_709_551_615 # word 0: 709551615 # word 1: 446744073 @@ -1677,7 +2049,11 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): @always_inline def is_uint128_overflow(self) -> Bool: - """Returns True if the BigUInt larger than UInt128.MAX.""" + """Returns True if the BigUInt larger than UInt128.MAX. + + Returns: + `True` if the value exceeds `UInt128.MAX`, `False` otherwise. + """ # UInt128.MAX: 340_282_366_920_938_463_463_374_607_431_768_211_455 # word 0: 768211455 # word 1: 374607431 @@ -1750,6 +2126,9 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): Notes: Zero has 1 digit. + + Returns: + The total number of decimal digits in the BigUInt. """ if self.is_zero(): debug_assert(len(self.words) == 1, "There are leading zero words.") @@ -1763,11 +2142,19 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): return result def number_of_words(self) -> Int: - """Returns the number of words in the BigUInt.""" + """Returns the number of words in the BigUInt. + + Returns: + The number of `UInt32` words in the internal representation. + """ return len(self.words) def number_of_trailing_zeros(self) -> Int: - """Returns the number of trailing zeros in the BigUInt.""" + """Returns the number of trailing zeros in the BigUInt. + + Returns: + The count of trailing zero digits in the decimal representation. + """ var result: Int = 0 for i in range(len(self.words)): if self.words[i] == 0: diff --git a/src/decimo/biguint/exponential.mojo b/src/decimo/biguint/exponential.mojo index 9e69edb0..2abaf0f8 100644 --- a/src/decimo/biguint/exponential.mojo +++ b/src/decimo/biguint/exponential.mojo @@ -138,6 +138,12 @@ def sqrt_initial_guess(x: BigUInt) -> BigUInt: The words of the BigUInt should be more than 2. The initial guess is always smaller or equal to the actual square root. + + Args: + x: The `BigUInt` value to estimate the square root of. + + Returns: + An initial guess that is less than or equal to the actual square root. """ # Yuhao ZHU: diff --git a/src/decimo/decimal128/constants.mojo b/src/decimo/decimal128/constants.mojo index b9b5bb67..6b09fa5e 100644 --- a/src/decimo/decimal128/constants.mojo +++ b/src/decimo/decimal128/constants.mojo @@ -31,67 +31,111 @@ from decimo.decimal128.decimal128 import Decimal128 @always_inline def M0() -> Decimal128: - """Returns 0 as a Decimal128.""" + """Returns 0 as a Decimal128. + + Returns: + The `Decimal128` value 0. + """ return Decimal128(0x0, 0x0, 0x0, 0x0) @always_inline def M1() -> Decimal128: - """Returns 1 as a Decimal128.""" + """Returns 1 as a Decimal128. + + Returns: + The `Decimal128` value 1. + """ return Decimal128(0x1, 0x0, 0x0, 0x0) @always_inline def M2() -> Decimal128: - """Returns 2 as a Decimal128.""" + """Returns 2 as a Decimal128. + + Returns: + The `Decimal128` value 2. + """ return Decimal128(0x2, 0x0, 0x0, 0x0) @always_inline def M3() -> Decimal128: - """Returns 3 as a Decimal128.""" + """Returns 3 as a Decimal128. + + Returns: + The `Decimal128` value 3. + """ return Decimal128(0x3, 0x0, 0x0, 0x0) @always_inline def M4() -> Decimal128: - """Returns 4 as a Decimal128.""" + """Returns 4 as a Decimal128. + + Returns: + The `Decimal128` value 4. + """ return Decimal128(0x4, 0x0, 0x0, 0x0) @always_inline def M5() -> Decimal128: - """Returns 5 as a Decimal128.""" + """Returns 5 as a Decimal128. + + Returns: + The `Decimal128` value 5. + """ return Decimal128(0x5, 0x0, 0x0, 0x0) @always_inline def M6() -> Decimal128: - """Returns 6 as a Decimal128.""" + """Returns 6 as a Decimal128. + + Returns: + The `Decimal128` value 6. + """ return Decimal128(0x6, 0x0, 0x0, 0x0) @always_inline def M7() -> Decimal128: - """Returns 7 as a Decimal128.""" + """Returns 7 as a Decimal128. + + Returns: + The `Decimal128` value 7. + """ return Decimal128(0x7, 0x0, 0x0, 0x0) @always_inline def M8() -> Decimal128: - """Returns 8 as a Decimal128.""" + """Returns 8 as a Decimal128. + + Returns: + The `Decimal128` value 8. + """ return Decimal128(0x8, 0x0, 0x0, 0x0) @always_inline def M9() -> Decimal128: - """Returns 9 as a Decimal128.""" + """Returns 9 as a Decimal128. + + Returns: + The `Decimal128` value 9. + """ return Decimal128(0x9, 0x0, 0x0, 0x0) @always_inline def M10() -> Decimal128: - """Returns 10 as a Decimal128.""" + """Returns 10 as a Decimal128. + + Returns: + The `Decimal128` value 10. + """ return Decimal128(0xA, 0x0, 0x0, 0x0) @@ -100,13 +144,21 @@ def M10() -> Decimal128: @always_inline def M0D5() -> Decimal128: - """Returns 0.5 as a Decimal128.""" + """Returns 0.5 as a Decimal128. + + Returns: + The `Decimal128` value 0.5. + """ return Decimal128(5, 0, 0, 0x10000) @always_inline def M0D25() -> Decimal128: - """Returns 0.25 as a Decimal128.""" + """Returns 0.25 as a Decimal128. + + Returns: + The `Decimal128` value 0.25. + """ return Decimal128(25, 0, 0, 0x20000) @@ -119,127 +171,211 @@ def M0D25() -> Decimal128: @always_inline def INV2() -> Decimal128: - """Returns 1/2 = 0.5.""" + """Returns 1/2 = 0.5. + + Returns: + The `Decimal128` representation of 1/2. + """ return Decimal128(0x5, 0x0, 0x0, 0x10000) @always_inline def INV10() -> Decimal128: - """Returns 1/10 = 0.1.""" + """Returns 1/10 = 0.1. + + Returns: + The `Decimal128` representation of 1/10. + """ return Decimal128(0x1, 0x0, 0x0, 0x10000) @always_inline def INV0D1() -> Decimal128: - """Returns 1/0.1 = 10.""" + """Returns 1/0.1 = 10. + + Returns: + The `Decimal128` representation of 1/0.1. + """ return Decimal128(0xA, 0x0, 0x0, 0x0) @always_inline def INV0D2() -> Decimal128: - """Returns 1/0.2 = 5.""" + """Returns 1/0.2 = 5. + + Returns: + The `Decimal128` representation of 1/0.2. + """ return Decimal128(0x5, 0x0, 0x0, 0x0) @always_inline def INV0D3() -> Decimal128: - """Returns 1/0.3 = 3.33333333333333333333333333333333...""" + """Returns 1/0.3 = 3.33333333333333333333333333333333... + + Returns: + The `Decimal128` representation of 1/0.3. + """ return Decimal128(0x35555555, 0xCF2607EE, 0x6BB4AFE4, 0x1C0000) @always_inline def INV0D4() -> Decimal128: - """Returns 1/0.4 = 2.5.""" + """Returns 1/0.4 = 2.5. + + Returns: + The `Decimal128` representation of 1/0.4. + """ return Decimal128(0x19, 0x0, 0x0, 0x10000) @always_inline def INV0D5() -> Decimal128: - """Returns 1/0.5 = 2.""" + """Returns 1/0.5 = 2. + + Returns: + The `Decimal128` representation of 1/0.5. + """ return Decimal128(0x2, 0x0, 0x0, 0x0) @always_inline def INV0D6() -> Decimal128: - """Returns 1/0.6 = 1.66666666666666666666666666666667...""" + """Returns 1/0.6 = 1.66666666666666666666666666666667... + + Returns: + The `Decimal128` representation of 1/0.6. + """ return Decimal128(0x1AAAAAAB, 0x679303F7, 0x35DA57F2, 0x1C0000) @always_inline def INV0D7() -> Decimal128: - """Returns 1/0.7 = 1.42857142857142857142857142857143...""" + """Returns 1/0.7 = 1.42857142857142857142857142857143... + + Returns: + The `Decimal128` representation of 1/0.7. + """ return Decimal128(0xCDB6DB6E, 0x3434DED3, 0x2E28DDAB, 0x1C0000) @always_inline def INV0D8() -> Decimal128: - """Returns 1/0.8 = 1.25.""" + """Returns 1/0.8 = 1.25. + + Returns: + The `Decimal128` representation of 1/0.8. + """ return Decimal128(0x7D, 0x0, 0x0, 0x20000) @always_inline def INV0D9() -> Decimal128: - """Returns 1/0.9 = 1.11111111111111111111111111111111...""" + """Returns 1/0.9 = 1.11111111111111111111111111111111... + + Returns: + The `Decimal128` representation of 1/0.9. + """ return Decimal128(0x671C71C7, 0x450CAD4F, 0x23E6E54C, 0x1C0000) @always_inline def INV1() -> Decimal128: - """Returns 1/1 = 1.""" + """Returns 1/1 = 1. + + Returns: + The `Decimal128` representation of 1/1. + """ return Decimal128(0x1, 0x0, 0x0, 0x0) @always_inline def INV1D1() -> Decimal128: - """Returns 1/1.1 = 0.90909090909090909090909090909091...""" + """Returns 1/1.1 = 0.90909090909090909090909090909091... + + Returns: + The `Decimal128` representation of 1/1.1. + """ return Decimal128(0x9A2E8BA3, 0x4FC48DCC, 0x1D5FD2E1, 0x1C0000) @always_inline def INV1D2() -> Decimal128: - """Returns 1/1.2 = 0.83333333333333333333333333333333...""" + """Returns 1/1.2 = 0.83333333333333333333333333333333... + + Returns: + The `Decimal128` representation of 1/1.2. + """ return Decimal128(0x8D555555, 0x33C981FB, 0x1AED2BF9, 0x1C0000) @always_inline def INV1D3() -> Decimal128: - """Returns 1/1.3 = 0.76923076923076923076923076923077...""" + """Returns 1/1.3 = 0.76923076923076923076923076923077... + + Returns: + The `Decimal128` representation of 1/1.3. + """ return Decimal128(0xC4EC4EC, 0x9243DA72, 0x18DAED83, 0x1C0000) @always_inline def INV1D4() -> Decimal128: - """Returns 1/1.4 = 0.71428571428571428571428571428571...""" + """Returns 1/1.4 = 0.71428571428571428571428571428571... + + Returns: + The `Decimal128` representation of 1/1.4. + """ return Decimal128(0xE6DB6DB7, 0x9A1A6F69, 0x17146ED5, 0x1C0000) @always_inline def INV1D5() -> Decimal128: - """Returns 1/1.5 = 0.66666666666666666666666666666667...""" + """Returns 1/1.5 = 0.66666666666666666666666666666667... + + Returns: + The `Decimal128` representation of 1/1.5. + """ return Decimal128(0xAAAAAAB, 0x296E0196, 0x158A8994, 0x1C0000) @always_inline def INV1D6() -> Decimal128: - """Returns 1/1.6 = 0.625.""" + """Returns 1/1.6 = 0.625. + + Returns: + The `Decimal128` representation of 1/1.6. + """ return Decimal128(0x271, 0x0, 0x0, 0x30000) @always_inline def INV1D7() -> Decimal128: - """Returns 1/1.7 = 0.58823529411764705882352941176471...""" + """Returns 1/1.7 = 0.58823529411764705882352941176471... + + Returns: + The `Decimal128` representation of 1/1.7. + """ return Decimal128(0x45A5A5A6, 0xE8520166, 0x1301C4AF, 0x1C0000) @always_inline def INV1D8() -> Decimal128: - """Returns 1/1.8 = 0.55555555555555555555555555555556...""" + """Returns 1/1.8 = 0.55555555555555555555555555555556... + + Returns: + The `Decimal128` representation of 1/1.8. + """ return Decimal128(0xB38E38E4, 0x228656A7, 0x11F372A6, 0x1C0000) @always_inline def INV1D9() -> Decimal128: - """Returns 1/1.9 = 0.52631578947368421052631578947368...""" + """Returns 1/1.9 = 0.52631578947368421052631578947368... + + Returns: + The `Decimal128` representation of 1/1.9. + """ return Decimal128(0xAA1AF287, 0x2E2E6D0A, 0x11019509, 0x1C0000) @@ -337,7 +473,11 @@ def N_DIVIDE_NEXT(n: Int) raises -> Decimal128: @always_inline def PI() -> Decimal128: - """Returns the value of pi (π) as a Decimal128.""" + """Returns the value of pi (π) as a Decimal128. + + Returns: + The value of pi (π). + """ return Decimal128(0x41B65F29, 0xB143885, 0x6582A536, 0x1C0000) @@ -361,109 +501,181 @@ def E() -> Decimal128: @always_inline def E2() -> Decimal128: - """Returns the value of e^2 as a Decimal128.""" + """Returns the value of e^2 as a Decimal128. + + Returns: + The value of e². + """ return Decimal128(0xE4DFDCAE, 0x89F7E295, 0xEEC0D6E9, 0x1C0000) @always_inline def E3() -> Decimal128: - """Returns the value of e^3 as a Decimal128.""" + """Returns the value of e^3 as a Decimal128. + + Returns: + The value of e³. + """ return Decimal128(0x236454F7, 0x62055A80, 0x40E65DE2, 0x1B0000) @always_inline def E4() -> Decimal128: - """Returns the value of e^4 as a Decimal128.""" + """Returns the value of e^4 as a Decimal128. + + Returns: + The value of e⁴. + """ return Decimal128(0x7121EFD3, 0xFB318FB5, 0xB06A87FB, 0x1B0000) @always_inline def E5() -> Decimal128: - """Returns the value of e^5 as a Decimal128.""" + """Returns the value of e^5 as a Decimal128. + + Returns: + The value of e⁵. + """ return Decimal128(0xD99BD974, 0x9F4BE5C7, 0x2FF472E3, 0x1A0000) @always_inline def E6() -> Decimal128: - """Returns the value of e^6 as a Decimal128.""" + """Returns the value of e^6 as a Decimal128. + + Returns: + The value of e⁶. + """ return Decimal128(0xADB57A66, 0xBD7A423F, 0x825AD8FF, 0x1A0000) @always_inline def E7() -> Decimal128: - """Returns the value of e^7 as a Decimal128.""" + """Returns the value of e^7 as a Decimal128. + + Returns: + The value of e⁷. + """ return Decimal128(0x22313FCF, 0x64D5D12F, 0x236F230A, 0x190000) @always_inline def E8() -> Decimal128: - """Returns the value of e^8 as a Decimal128.""" + """Returns the value of e^8 as a Decimal128. + + Returns: + The value of e⁸. + """ return Decimal128(0x1E892E63, 0xD1BF8B5C, 0x6051E812, 0x190000) @always_inline def E9() -> Decimal128: - """Returns the value of e^9 as a Decimal128.""" + """Returns the value of e^9 as a Decimal128. + + Returns: + The value of e⁹. + """ return Decimal128(0x34FAB691, 0xE7CD8DEA, 0x1A2EB6C3, 0x180000) @always_inline def E10() -> Decimal128: - """Returns the value of e^10 as a Decimal128.""" + """Returns the value of e^10 as a Decimal128. + + Returns: + The value of e¹⁰. + """ return Decimal128(0xBA7F4F65, 0x58692B62, 0x472BDD8F, 0x180000) @always_inline def E11() -> Decimal128: - """Returns the value of e^11 as a Decimal128.""" + """Returns the value of e^11 as a Decimal128. + + Returns: + The value of e¹¹. + """ return Decimal128(0x8C2C6D20, 0x2A86F9E7, 0xC176BAAE, 0x180000) @always_inline def E12() -> Decimal128: - """Returns the value of e^12 as a Decimal128.""" + """Returns the value of e^12 as a Decimal128. + + Returns: + The value of e¹². + """ return Decimal128(0xE924992A, 0x31CDC314, 0x3496C2C4, 0x170000) @always_inline def E13() -> Decimal128: - """Returns the value of e^13 as a Decimal128.""" + """Returns the value of e^13 as a Decimal128. + + Returns: + The value of e¹³. + """ return Decimal128(0x220130DB, 0xC386029A, 0x8EF393FB, 0x170000) @always_inline def E14() -> Decimal128: - """Returns the value of e^14 as a Decimal128.""" + """Returns the value of e^14 as a Decimal128. + + Returns: + The value of e¹⁴. + """ return Decimal128(0x3A24795C, 0xC412DF01, 0x26DBB5A0, 0x160000) @always_inline def E15() -> Decimal128: - """Returns the value of e^15 as a Decimal128.""" + """Returns the value of e^15 as a Decimal128. + + Returns: + The value of e¹⁵. + """ return Decimal128(0x6C1248BD, 0x90456557, 0x69A0AD8C, 0x160000) @always_inline def E16() -> Decimal128: - """Returns the value of e^16 as a Decimal128.""" + """Returns the value of e^16 as a Decimal128. + + Returns: + The value of e¹⁶. + """ return Decimal128(0xB46A97D, 0x90655BBD, 0x1CB66B18, 0x150000) @always_inline def E32() -> Decimal128: - """Returns the value of e^32 as a Decimal128.""" + """Returns the value of e^32 as a Decimal128. + + Returns: + The value of e³². + """ return Decimal128(0x18420EB, 0xCC2501E6, 0xFF24A138, 0xF0000) @always_inline def E0D5() -> Decimal128: - """Returns the value of e^0.5 = e^(1/2) as a Decimal128.""" + """Returns the value of e^0.5 = e^(1/2) as a Decimal128. + + Returns: + The value of e^(1/2). + """ return Decimal128(0x8E99DD66, 0xC210E35C, 0x3545E717, 0x1C0000) @always_inline def E0D25() -> Decimal128: - """Returns the value of e^0.25 = e^(1/4) as a Decimal128.""" + """Returns the value of e^0.25 = e^(1/4) as a Decimal128. + + Returns: + The value of e^(1/4). + """ return Decimal128(0xB43646F1, 0x2654858A, 0x297D3595, 0x1C0000) @@ -493,74 +705,122 @@ def E0D25() -> Decimal128: @always_inline def LN1() -> Decimal128: - """Returns ln(1) = 0.""" + """Returns ln(1) = 0. + + Returns: + The natural logarithm of 1. + """ return Decimal128(0x0, 0x0, 0x0, 0x0) @always_inline def LN2() -> Decimal128: - """Returns ln(2) = 0.69314718055994530941723212145818...""" + """Returns ln(2) = 0.69314718055994530941723212145818... + + Returns: + The natural logarithm of 2. + """ return Decimal128(0xAA7A65BF, 0x81F52F01, 0x1665943F, 0x1C0000) @always_inline def LN10() -> Decimal128: - """Returns ln(10) = 2.30258509299404568401799145468436...""" + """Returns ln(10) = 2.30258509299404568401799145468436... + + Returns: + The natural logarithm of 10. + """ return Decimal128(0x9FA69733, 0x1414B220, 0x4A668998, 0x1C0000) # Constants for values less than 1 @always_inline def LN0D1() -> Decimal128: - """Returns ln(0.1) = -2.30258509299404568401799145468436...""" + """Returns ln(0.1) = -2.30258509299404568401799145468436... + + Returns: + The natural logarithm of 0.1. + """ return Decimal128(0x9FA69733, 0x1414B220, 0x4A668998, 0x801C0000) @always_inline def LN0D2() -> Decimal128: - """Returns ln(0.2) = -1.60943791243410037460075933322619...""" + """Returns ln(0.2) = -1.60943791243410037460075933322619... + + Returns: + The natural logarithm of 0.2. + """ return Decimal128(0xF52C3174, 0x921F831E, 0x3400F558, 0x801C0000) @always_inline def LN0D3() -> Decimal128: - """Returns ln(0.3) = -1.20397280432593599262274621776184...""" + """Returns ln(0.3) = -1.20397280432593599262274621776184... + + Returns: + The natural logarithm of 0.3. + """ return Decimal128(0x2B8E6822, 0x8258467, 0x26E70795, 0x801C0000) @always_inline def LN0D4() -> Decimal128: - """Returns ln(0.4) = -0.91629073187415506518352721176801...""" + """Returns ln(0.4) = -0.91629073187415506518352721176801... + + Returns: + The natural logarithm of 0.4. + """ return Decimal128(0x4AB1CBB6, 0x102A541D, 0x1D9B6119, 0x801C0000) @always_inline def LN0D5() -> Decimal128: - """Returns ln(0.5) = -0.69314718055994530941723212145818...""" + """Returns ln(0.5) = -0.69314718055994530941723212145818... + + Returns: + The natural logarithm of 0.5. + """ return Decimal128(0xAA7A65BF, 0x81F52F01, 0x1665943F, 0x801C0000) @always_inline def LN0D6() -> Decimal128: - """Returns ln(0.6) = -0.51082562376599068320551409630366...""" + """Returns ln(0.6) = -0.51082562376599068320551409630366... + + Returns: + The natural logarithm of 0.6. + """ return Decimal128(0x81140263, 0x86305565, 0x10817355, 0x801C0000) @always_inline def LN0D7() -> Decimal128: - """Returns ln(0.7) = -0.35667494393873237891263871124118...""" + """Returns ln(0.7) = -0.35667494393873237891263871124118... + + Returns: + The natural logarithm of 0.7. + """ return Decimal128(0x348BC5A8, 0x8B755D08, 0xB865892, 0x801C0000) @always_inline def LN0D8() -> Decimal128: - """Returns ln(0.8) = -0.22314355131420975576629509030983...""" + """Returns ln(0.8) = -0.22314355131420975576629509030983... + + Returns: + The natural logarithm of 0.8. + """ return Decimal128(0xA03765F7, 0x8E35251B, 0x735CCD9, 0x801C0000) @always_inline def LN0D9() -> Decimal128: - """Returns ln(0.9) = -0.10536051565782630122750098083931...""" + """Returns ln(0.9) = -0.10536051565782630122750098083931... + + Returns: + The natural logarithm of 0.9. + """ return Decimal128(0xB7763910, 0xFC3656AD, 0x3678591, 0x801C0000) @@ -569,53 +829,89 @@ def LN0D9() -> Decimal128: @always_inline def LN1D1() -> Decimal128: - """Returns ln(1.1) = 0.09531017980432486004395212328077...""" + """Returns ln(1.1) = 0.09531017980432486004395212328077... + + Returns: + The natural logarithm of 1.1. + """ return Decimal128(0x7212FFD1, 0x7D9A10, 0x3146328, 0x1C0000) @always_inline def LN1D2() -> Decimal128: - """Returns ln(1.2) = 0.18232155679395462621171802515451...""" + """Returns ln(1.2) = 0.18232155679395462621171802515451... + + Returns: + The natural logarithm of 1.2. + """ return Decimal128(0x2966635C, 0xFBC4D99C, 0x5E420E9, 0x1C0000) @always_inline def LN1D3() -> Decimal128: - """Returns ln(1.3) = 0.26236426446749105203549598688095...""" + """Returns ln(1.3) = 0.26236426446749105203549598688095... + + Returns: + The natural logarithm of 1.3. + """ return Decimal128(0xE0BE71FD, 0xC254E078, 0x87A39F0, 0x1C0000) @always_inline def LN1D4() -> Decimal128: - """Returns ln(1.4) = 0.33647223662121293050459341021699...""" + """Returns ln(1.4) = 0.33647223662121293050459341021699... + + Returns: + The natural logarithm of 1.4. + """ return Decimal128(0x75EEA016, 0xF67FD1F9, 0xADF3BAC, 0x1C0000) @always_inline def LN1D5() -> Decimal128: - """Returns ln(1.5) = 0.40546510810816438197801311546435...""" + """Returns ln(1.5) = 0.40546510810816438197801311546435... + + Returns: + The natural logarithm of 1.5. + """ return Decimal128(0xC99DC953, 0x89F9FEB7, 0xD19EDC3, 0x1C0000) @always_inline def LN1D6() -> Decimal128: - """Returns ln(1.6) = 0.47000362924573555365093703114834...""" + """Returns ln(1.6) = 0.47000362924573555365093703114834... + + Returns: + The natural logarithm of 1.6. + """ return Decimal128(0xA42FFC8, 0xF3C009E6, 0xF2FC765, 0x1C0000) @always_inline def LN1D7() -> Decimal128: - """Returns ln(1.7) = 0.53062825106217039623154316318876...""" + """Returns ln(1.7) = 0.53062825106217039623154316318876... + + Returns: + The natural logarithm of 1.7. + """ return Decimal128(0x64BB9ED0, 0x4AB9978F, 0x11254107, 0x1C0000) @always_inline def LN1D8() -> Decimal128: - """Returns ln(1.8) = 0.58778666490211900818973114061886...""" + """Returns ln(1.8) = 0.58778666490211900818973114061886... + + Returns: + The natural logarithm of 1.8. + """ return Decimal128(0xF3042CAE, 0x85BED853, 0x12FE0EAD, 0x1C0000) @always_inline def LN1D9() -> Decimal128: - """Returns ln(1.9) = 0.64185388617239477599103597720349...""" + """Returns ln(1.9) = 0.64185388617239477599103597720349... + + Returns: + The natural logarithm of 1.9. + """ return Decimal128(0x12F992DC, 0xE7374425, 0x14BD4A78, 0x1C0000) diff --git a/src/decimo/decimal128/decimal128.mojo b/src/decimo/decimal128/decimal128.mojo index 142f10b2..3d87d107 100644 --- a/src/decimo/decimal128/decimal128.mojo +++ b/src/decimo/decimal128/decimal128.mojo @@ -102,10 +102,15 @@ struct Decimal128( # Constants comptime MAX_SCALE: Int = 28 + """The maximum scale (exponent) value for `Decimal128` (28).""" comptime MAX_AS_UINT128 = UInt128(79228162514264337593543950335) + """The maximum coefficient value as `UInt128`.""" comptime MAX_AS_INT128 = Int128(79228162514264337593543950335) + """The maximum coefficient value as `Int128`.""" comptime MAX_AS_UINT256 = UInt256(79228162514264337593543950335) + """The maximum coefficient value as `UInt256`.""" comptime MAX_AS_INT256 = Int256(79228162514264337593543950335) + """The maximum coefficient value as `Int256`.""" comptime MAX_AS_STRING = String("79228162514264337593543950335") """Maximum value as a string.""" comptime MAX_NUM_DIGITS = 29 @@ -132,6 +137,9 @@ struct Decimal128( def INFINITY() -> Self: """Returns a Decimal representing positive infinity. Internal representation: `0b0000_0000_0000_0000_0000_0000_0001`. + + Returns: + A `Decimal128` representing positive infinity. """ return Self(0, 0, 0, 0x00000001) @@ -140,6 +148,9 @@ struct Decimal128( def NEGATIVE_INFINITY() -> Self: """Returns a Decimal128 representing negative infinity. Internal representation: `0b1000_0000_0000_0000_0000_0000_0001`. + + Returns: + A `Decimal128` representing negative infinity. """ return Self(0, 0, 0, 0x80000001) @@ -148,6 +159,9 @@ struct Decimal128( def NAN() -> Self: """Returns a Decimal128 representing Not a Number (NaN). Internal representation: `0b0000_0000_0000_0000_0000_0000_0010`. + + Returns: + A `Decimal128` representing NaN. """ return Self(0, 0, 0, 0x00000010) @@ -156,19 +170,30 @@ struct Decimal128( def NEGATIVE_NAN() -> Self: """Returns a Decimal128 representing negative Not a Number. Internal representation: `0b1000_0000_0000_0000_0000_0000_0010`. + + Returns: + A `Decimal128` representing negative NaN. """ return Self(0, 0, 0, 0x80000010) @always_inline @staticmethod def ZERO() -> Decimal128: - """Returns a Decimal128 representing 0.""" + """Returns a Decimal128 representing 0. + + Returns: + A `Decimal128` representing zero. + """ return Self(0, 0, 0, 0) @always_inline @staticmethod def ONE() -> Decimal128: - """Returns a Decimal128 representing 1.""" + """Returns a Decimal128 representing 1. + + Returns: + A `Decimal128` representing one. + """ return Self(1, 0, 0, 0) @always_inline @@ -177,6 +202,9 @@ struct Decimal128( """ Returns the maximum possible Decimal128 value. This is equivalent to 79228162514264337593543950335. + + Returns: + The maximum `Decimal128` value. """ return Self(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0) @@ -185,19 +213,30 @@ struct Decimal128( def MIN() -> Decimal128: """Returns the minimum possible Decimal128 value (negative of MAX). This is equivalent to -79228162514264337593543950335. + + Returns: + The minimum `Decimal128` value. """ return Self(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, Decimal128.SIGN_MASK) @always_inline @staticmethod def PI() -> Decimal128: - """Returns the value of pi (π) as a Decimal128.""" + """Returns the value of pi (π) as a Decimal128. + + Returns: + The value of pi (π). + """ return decimo.decimal128.constants.PI() @always_inline @staticmethod def E() -> Decimal128: - """Returns the value of Euler's number (e) as a Decimal128.""" + """Returns the value of Euler's number (e) as a Decimal128. + + Returns: + The value of Euler's number (e). + """ return decimo.decimal128.constants.E() # ===------------------------------------------------------------------=== # @@ -217,6 +256,12 @@ struct Decimal128( """Initializes a Decimal128 with four raw words of internal representation. ***WARNING***: This method does not check the flags. If you are not sure about the flags, use `Decimal128.from_words()` instead. + + Args: + low: The least significant 32 bits of the coefficient. + mid: The middle 32 bits of the coefficient. + high: The most significant 32 bits of the coefficient. + flags: The raw flags word containing scale and sign. """ self.low = low @@ -234,6 +279,13 @@ struct Decimal128( ) raises: """Initializes a Decimal128 with five components. See `Decimal128.from_components()` for more information. + + Args: + low: The least significant 32 bits of the coefficient. + mid: The middle 32 bits of the coefficient. + high: The most significant 32 bits of the coefficient. + scale: The number of decimal places (0-28). + sign: `True` if the number is negative, `False` otherwise. """ try: @@ -246,12 +298,19 @@ struct Decimal128( def __init__(out self, value: Int): """Initializes a Decimal128 from an integer. See `from_int()` for more information. + + Args: + value: The integer value to convert. """ self = Decimal128.from_int(value) def __init__(out self, value: Int, scale: UInt32) raises: """Initializes a Decimal128 from an integer. See `from_int()` for more information. + + Args: + value: The integer value to convert. + scale: The number of decimal places (0-28). """ try: self = Decimal128.from_int(value, scale) @@ -261,6 +320,9 @@ struct Decimal128( def __init__(out self, value: String) raises: """Initializes a Decimal128 from a string representation. See `from_string()` for more information. + + Args: + value: The string representation of the decimal number. """ try: self = Decimal128.from_string(value) @@ -270,6 +332,9 @@ struct Decimal128( def __init__(out self, value: Float64) raises: """Initializes a Decimal128 from a floating-point value. See `from_float` for more information. + + Args: + value: The floating-point value to convert. """ try: @@ -883,12 +948,20 @@ struct Decimal128( @always_inline def copy(self) -> Self: - """Returns a copy of the Decimal128.""" + """Returns a copy of the Decimal128. + + Returns: + A copy of this `Decimal128`. + """ return Self(self.low, self.mid, self.high, self.flags) @always_inline def clone(self) -> Self: - """Returns a copy of the Decimal128.""" + """Returns a copy of the Decimal128. + + Returns: + A copy of this `Decimal128`. + """ return Self(self.low, self.mid, self.high, self.flags) # ===------------------------------------------------------------------=== # @@ -911,11 +984,21 @@ struct Decimal128( def __int__(self) raises -> Int: """Returns the integral part of the Decimal128 as Int. See `to_int()` for more information. + + Returns: + The `Int` representation. """ return self.to_int() def write_repr_to[W: Writer](self, mut writer: W): - """Writes the debug representation to a writer.""" + """Writes the debug representation to a writer. + + Parameters: + W: A type conforming to the `Writer` interface. + + Args: + writer: The writer instance. + """ writer.write('Decimal128("', self.to_str(), '")') # ===------------------------------------------------------------------=== # @@ -925,12 +1008,21 @@ struct Decimal128( def write_to[W: Writer](self, mut writer: W): """Writes the Decimal128 to a writer. This implement the `write` method of the `Writer` trait. + + Parameters: + W: A type conforming to the `Writer` interface. + + Args: + writer: The writer instance. """ writer.write(self.to_str()) def repr_words(self) -> String: """Returns a string representation of the Decimal128's internal words. `Decimal128.from_words(low, mid, high, flags)`. + + Returns: + A string in the format `Decimal128(low, mid, high, flags)`. """ return ( "Decimal128(" @@ -947,6 +1039,9 @@ struct Decimal128( def repr_components(self) -> String: """Returns a string representation of the Decimal128's five components. `Decimal128.from_components(low, mid, high, scale, sign)`. + + Returns: + A string in the format `Decimal128(low=, mid=, high=, scale=, sign=)`. """ var scale = UInt8((self.flags & Self.SCALE_MASK) >> Self.SCALE_SHIFT) var sign = Bool((self.flags & Self.SIGN_MASK) == Self.SIGN_MASK) @@ -1000,14 +1095,22 @@ struct Decimal128( return Int64(result & 0xFFFF_FFFF_FFFF_FFFF) def to_int128(self) -> Int128: - """Returns the signed integral part of the Decimal128.""" + """Returns the signed integral part of the Decimal128. + + Returns: + The signed integral part as `Int128`. + """ var res = Int128(self.to_uint128()) return -res if self.is_negative() else res def to_uint128(self) -> UInt128: - """Returns the absolute integral part of the Decimal128 as UInt128.""" + """Returns the absolute integral part of the Decimal128 as UInt128. + + Returns: + The absolute integral part as `UInt128`. + """ var res: UInt128 if self.is_zero(): @@ -1031,6 +1134,9 @@ struct Decimal128( def to_str(self) -> String: """Returns string representation of the Decimal128. Preserves trailing zeros after decimal128 point to match the scale. + + Returns: + The string representation of this `Decimal128`. """ # Get the coefficient as a string (absolute value) var coef = String(self.coefficient()) @@ -1144,6 +1250,9 @@ struct Decimal128( def __abs__(self) -> Self: """Returns the absolute value of this Decimal128. See `absolute()` for more information. + + Returns: + The absolute value. """ return decimo.decimal128.arithmetics.absolute(self) @@ -1151,6 +1260,9 @@ struct Decimal128( def __neg__(self) -> Self: """Returns the negation of this Decimal128. See `negative()` for more information. + + Returns: + The negated value. """ return decimo.decimal128.arithmetics.negative(self) @@ -1162,62 +1274,170 @@ struct Decimal128( @always_inline def __add__(self, other: Self) raises -> Self: + """Adds two values. + + Args: + other: The right-hand side operand. + + Returns: + The sum. + """ return decimo.decimal128.arithmetics.add(self, other) @always_inline def __add__(self, other: Int) raises -> Self: + """Adds two values. + + Args: + other: The right-hand side operand. + + Returns: + The sum. + """ return decimo.decimal128.arithmetics.add(self, Self(other)) @always_inline def __sub__(self, other: Self) raises -> Self: + """Subtracts two values. + + Args: + other: The right-hand side operand. + + Returns: + The difference. + """ return decimo.decimal128.arithmetics.subtract(self, other) @always_inline def __sub__(self, other: Int) raises -> Self: + """Subtracts two values. + + Args: + other: The right-hand side operand. + + Returns: + The difference. + """ return decimo.decimal128.arithmetics.subtract(self, Self(other)) @always_inline def __mul__(self, other: Self) raises -> Self: + """Multiplies two values. + + Args: + other: The right-hand side operand. + + Returns: + The product. + """ return decimo.decimal128.arithmetics.multiply(self, other) @always_inline def __mul__(self, other: Int) raises -> Self: + """Multiplies two values. + + Args: + other: The right-hand side operand. + + Returns: + The product. + """ return decimo.decimal128.arithmetics.multiply(self, Self(other)) @always_inline def __truediv__(self, other: Self) raises -> Self: + """Divides two values using true division. + + Args: + other: The right-hand side operand. + + Returns: + The quotient. + """ return decimo.decimal128.arithmetics.divide(self, other) @always_inline def __truediv__(self, other: Int) raises -> Self: + """Divides two values using true division. + + Args: + other: The right-hand side operand. + + Returns: + The quotient. + """ return decimo.decimal128.arithmetics.divide(self, Self(other)) @always_inline def __floordiv__(self, other: Self) raises -> Self: - """Performs truncate division with // operator.""" + """Performs truncate division with // operator. + + Args: + other: The right-hand side operand. + + Returns: + The truncated quotient. + """ return decimo.decimal128.arithmetics.truncate_divide(self, other) @always_inline def __floordiv__(self, other: Int) raises -> Self: - """Performs truncate division with // operator.""" + """Performs truncate division with // operator. + + Args: + other: The right-hand side operand. + + Returns: + The truncated quotient. + """ return decimo.decimal128.arithmetics.truncate_divide(self, Self(other)) @always_inline def __mod__(self, other: Self) raises -> Self: - """Performs truncate modulo.""" + """Performs truncate modulo. + + Args: + other: The right-hand side operand. + + Returns: + The remainder. + """ return decimo.decimal128.arithmetics.modulo(self, other) @always_inline def __mod__(self, other: Int) raises -> Self: - """Performs truncate modulo.""" + """Performs truncate modulo. + + Args: + other: The right-hand side operand. + + Returns: + The remainder. + """ return decimo.decimal128.arithmetics.modulo(self, Self(other)) @always_inline def __pow__(self, exponent: Self) raises -> Self: + """Raises to a power. + + Args: + exponent: The exponent to raise to. + + Returns: + The value raised to the given power. + """ return decimo.decimal128.exponential.power(self, exponent) @always_inline def __pow__(self, exponent: Int) raises -> Self: + """Raises to a power. + + Args: + exponent: The exponent to raise to. + + Returns: + The value raised to the given power. + """ return decimo.decimal128.exponential.power(self, exponent) # ===------------------------------------------------------------------=== # @@ -1229,28 +1449,74 @@ struct Decimal128( @always_inline def __radd__(self, other: Int) raises -> Self: + """Adds two values (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The sum. + """ return decimo.decimal128.arithmetics.add(Self(other), self) @always_inline def __rsub__(self, other: Int) raises -> Self: + """Subtracts two values (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The difference. + """ return decimo.decimal128.arithmetics.subtract(Self(other), self) @always_inline def __rmul__(self, other: Int) raises -> Self: + """Multiplies two values (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The product. + """ return decimo.decimal128.arithmetics.multiply(Self(other), self) @always_inline def __rtruediv__(self, other: Int) raises -> Self: + """Divides two values using true division (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The quotient. + """ return decimo.decimal128.arithmetics.divide(Self(other), self) @always_inline def __rfloordiv__(self, other: Int) raises -> Self: - """Performs truncate division with // operator.""" + """Performs truncate division with // operator (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The truncated quotient. + """ return decimo.decimal128.arithmetics.truncate_divide(Self(other), self) @always_inline def __rmod__(self, other: Int) raises -> Self: - """Performs truncate modulo.""" + """Performs truncate modulo (reflected). + + Args: + other: The left-hand side operand. + + Returns: + The remainder. + """ return decimo.decimal128.arithmetics.modulo(Self(other), self) # ===------------------------------------------------------------------=== # @@ -1262,49 +1528,101 @@ struct Decimal128( @always_inline def __iadd__(mut self, other: Self) raises: + """Adds in place. + + Args: + other: The right-hand side operand. + """ self = decimo.decimal128.arithmetics.add(self, other) @always_inline def __iadd__(mut self, other: Int) raises: + """Adds in place. + + Args: + other: The right-hand side operand. + """ self = decimo.decimal128.arithmetics.add(self, Self(other)) @always_inline def __isub__(mut self, other: Self) raises: + """Subtracts in place. + + Args: + other: The right-hand side operand. + """ self = decimo.decimal128.arithmetics.subtract(self, other) @always_inline def __isub__(mut self, other: Int) raises: + """Subtracts in place. + + Args: + other: The right-hand side operand. + """ self = decimo.decimal128.arithmetics.subtract(self, Self(other)) @always_inline def __imul__(mut self, other: Self) raises: + """Multiplies in place. + + Args: + other: The right-hand side operand. + """ self = decimo.decimal128.arithmetics.multiply(self, other) @always_inline def __imul__(mut self, other: Int) raises: + """Multiplies in place. + + Args: + other: The right-hand side operand. + """ self = decimo.decimal128.arithmetics.multiply(self, Self(other)) @always_inline def __itruediv__(mut self, other: Self) raises: + """Divides in place using true division. + + Args: + other: The right-hand side operand. + """ self = decimo.decimal128.arithmetics.divide(self, other) @always_inline def __itruediv__(mut self, other: Int) raises: + """Divides in place using true division. + + Args: + other: The right-hand side operand. + """ self = decimo.decimal128.arithmetics.divide(self, Self(other)) @always_inline def __ifloordiv__(mut self, other: Self) raises: - """Performs truncate division with // operator.""" + """Performs truncate division with // operator. + + Args: + other: The right-hand side operand. + """ self = decimo.decimal128.arithmetics.truncate_divide(self, other) @always_inline def __ifloordiv__(mut self, other: Int) raises: - """Performs truncate division with // operator.""" + """Performs truncate division with // operator. + + Args: + other: The right-hand side operand. + """ self = decimo.decimal128.arithmetics.truncate_divide(self, Self(other)) @always_inline def __imod__(mut self, other: Self) raises: - """Performs truncate modulo.""" + """Performs truncate modulo. + + Args: + other: The right-hand side operand. + """ self = decimo.decimal128.arithmetics.modulo(self, other) # ===------------------------------------------------------------------=== # @@ -1316,6 +1634,12 @@ struct Decimal128( def __gt__(self, other: Decimal128) -> Bool: """Greater than comparison operator. See `greater()` for more information. + + Args: + other: The value to compare against. + + Returns: + `True` if this value is greater than `other`, `False` otherwise. """ return decimo.decimal128.comparison.greater(self, other) @@ -1323,6 +1647,12 @@ struct Decimal128( def __lt__(self, other: Decimal128) -> Bool: """Less than comparison operator. See `less()` for more information. + + Args: + other: The value to compare against. + + Returns: + `True` if this value is less than `other`, `False` otherwise. """ return decimo.decimal128.comparison.less(self, other) @@ -1330,6 +1660,12 @@ struct Decimal128( def __ge__(self, other: Decimal128) -> Bool: """Greater than or equal comparison operator. See `greater_equal()` for more information. + + Args: + other: The value to compare against. + + Returns: + `True` if this value is greater than or equal to `other`, `False` otherwise. """ return decimo.decimal128.comparison.greater_equal(self, other) @@ -1337,6 +1673,12 @@ struct Decimal128( def __le__(self, other: Decimal128) -> Bool: """Less than or equal comparison operator. See `less_equal()` for more information. + + Args: + other: The value to compare against. + + Returns: + `True` if this value is less than or equal to `other`, `False` otherwise. """ return decimo.decimal128.comparison.less_equal(self, other) @@ -1344,6 +1686,12 @@ struct Decimal128( def __eq__(self, other: Decimal128) -> Bool: """Equality comparison operator. See `equal()` for more information. + + Args: + other: The value to compare against. + + Returns: + `True` if the values are equal, `False` otherwise. """ return decimo.decimal128.comparison.equal(self, other) @@ -1351,6 +1699,12 @@ struct Decimal128( def __ne__(self, other: Decimal128) -> Bool: """Inequality comparison operator. See `not_equal()` for more information. + + Args: + other: The value to compare against. + + Returns: + `True` if the values are not equal, `False` otherwise. """ return decimo.decimal128.comparison.not_equal(self, other) @@ -1367,6 +1721,12 @@ struct Decimal128( raises: Error: Calling `round()` failed. + + Args: + ndigits: The number of decimal places to round to. + + Returns: + The rounded `Decimal128` value. """ try: return decimo.decimal128.rounding.round( @@ -1379,7 +1739,11 @@ struct Decimal128( @always_inline def __round__(self) -> Self: - """**OVERLOAD**.""" + """**OVERLOAD**. + + Returns: + The `Decimal128` rounded to 0 decimal places. + """ try: return decimo.decimal128.rounding.round( self, ndigits=0, rounding_mode=RoundingMode.half_even() @@ -1403,6 +1767,13 @@ struct Decimal128( (1) Allows specifying the rounding mode. (2) Raises an error if the operation would result in overflow. See `round()` for more information. + + Args: + ndigits: The number of decimal places to round to. + rounding_mode: The rounding mode to apply. + + Returns: + The rounded `Decimal128` value. """ return decimo.decimal128.rounding.round( self, ndigits=ndigits, rounding_mode=rounding_mode @@ -1416,6 +1787,13 @@ struct Decimal128( ) raises -> Self: """Quantizes this Decimal128 to the specified exponent. See `quantize()` for more information. + + Args: + exp: A `Decimal128` whose scale determines the target precision. + rounding_mode: The rounding mode to apply. + + Returns: + The quantized `Decimal128` value. """ return decimo.decimal128.rounding.quantize(self, exp, rounding_mode) @@ -1423,6 +1801,9 @@ struct Decimal128( def exp(self) raises -> Self: """Calculates the exponential of this Decimal128. See `exp()` for more information. + + Returns: + The value of e raised to this power. """ return decimo.decimal128.exponential.exp(self) @@ -1430,33 +1811,67 @@ struct Decimal128( def ln(self) raises -> Self: """Calculates the natural logarithm of this Decimal128. See `ln()` for more information. + + Returns: + The natural logarithm of this value. """ return decimo.decimal128.exponential.ln(self) @always_inline def log10(self) raises -> Decimal128: - """Computes the base-10 logarithm of this Decimal128.""" + """Computes the base-10 logarithm of this Decimal128. + + Returns: + The base-10 logarithm of this value. + """ return decimo.decimal128.exponential.log10(self) @always_inline def log(self, base: Decimal128) raises -> Decimal128: - """Computes the logarithm of this Decimal128 with an arbitrary base.""" + """Computes the logarithm of this Decimal128 with an arbitrary base. + + Args: + base: The logarithm base. + + Returns: + The logarithm of this value in the given base. + """ return decimo.decimal128.exponential.log(self, base) @always_inline def power(self, exponent: Int) raises -> Decimal128: - """Raises this Decimal128 to the power of an integer.""" + """Raises this Decimal128 to the power of an integer. + + Args: + exponent: The integer exponent to raise to. + + Returns: + The value raised to the given power. + """ return decimo.decimal128.exponential.power(self, Self(exponent)) @always_inline def power(self, exponent: Decimal128) raises -> Decimal128: - """Raises this Decimal128 to the power of another Decimal128.""" + """Raises this Decimal128 to the power of another Decimal128. + + Args: + exponent: The `Decimal128` exponent to raise to. + + Returns: + The value raised to the given power. + """ return decimo.decimal128.exponential.power(self, exponent) @always_inline def root(self, n: Int) raises -> Self: """Calculates the n-th root of this Decimal128. See `root()` for more information. + + Args: + n: The degree of the root to compute. + + Returns: + The n-th root of this value. """ return decimo.decimal128.exponential.root(self, n) @@ -1464,6 +1879,9 @@ struct Decimal128( def sqrt(self) raises -> Self: """Calculates the square root of this Decimal128. See `sqrt()` for more information. + + Returns: + The square root of this value. """ return decimo.decimal128.exponential.sqrt(self) @@ -1577,7 +1995,11 @@ struct Decimal128( return result def internal_representation(self) -> String: - """Returns the internal representation details as a String.""" + """Returns the internal representation details as a String. + + Returns: + A formatted string showing all internal fields. + """ # All labels var labels = List[String]() labels.append("Decimal128:") @@ -1656,7 +2078,11 @@ struct Decimal128( @always_inline def is_negative(self) -> Bool: - """Returns True if this Decimal128 is negative.""" + """Returns True if this Decimal128 is negative. + + Returns: + `True` if negative, `False` otherwise. + """ return (self.flags & Self.SIGN_MASK) != 0 @always_inline @@ -1664,6 +2090,9 @@ struct Decimal128( """Returns True if this Decimal128 represents the value 1. If 10^scale == coefficient, then it's one. `1` and `1.00` are considered ones. + + Returns: + `True` if this value equals 1, `False` otherwise. """ if self.is_negative(): return False @@ -1684,22 +2113,36 @@ struct Decimal128( """Returns True if this Decimal128 represents zero. A decimal128 is zero when all coefficient parts (low, mid, high) are zero, regardless of its sign or scale. + + Returns: + `True` if this value is zero, `False` otherwise. """ return self.low == 0 and self.mid == 0 and self.high == 0 @always_inline def is_infinity(self) -> Bool: - """Returns True if this Decimal128 is positive or negative infinity.""" + """Returns True if this Decimal128 is positive or negative infinity. + + Returns: + `True` if infinity, `False` otherwise. + """ return (self.flags & Self.INFINITY_MASK) != 0 @always_inline def is_nan(self) -> Bool: - """Returns True if this Decimal128 is NaN (Not a Number).""" + """Returns True if this Decimal128 is NaN (Not a Number). + + Returns: + `True` if NaN, `False` otherwise. + """ return (self.flags & Self.NAN_MASK) != 0 @always_inline def scale(self) -> Int: """Returns the scale (number of decimal128 places) of this Decimal128. + + Returns: + The scale as an `Int`. """ return Int((self.flags & Self.SCALE_MASK) >> Self.SCALE_SHIFT) diff --git a/src/decimo/decimal128/utility.mojo b/src/decimo/decimal128/utility.mojo index 9cc012bc..0ebf7900 100644 --- a/src/decimo/decimal128/utility.mojo +++ b/src/decimo/decimal128/utility.mojo @@ -561,6 +561,15 @@ def number_of_bits[dtype: DType, //](var value: Scalar[dtype]) -> Int: Constraints: `dtype` must be integral. + + Parameters: + dtype: The scalar type of the input value. + + Args: + value: The integer value to count bits in. + + Returns: + The number of significant bits in the value. """ comptime assert dtype.is_integral(), "must be intergral" diff --git a/src/decimo/errors.mojo b/src/decimo/errors.mojo index 183fa913..786c7cdc 100644 --- a/src/decimo/errors.mojo +++ b/src/decimo/errors.mojo @@ -90,11 +90,6 @@ message: An optional message describing the error.\\ previous_error: An optional previous error that caused this error. """ -comptime HEADER_OF_ERROR_MESSAGE = """ ---------------------------------------------------------------------------- -DecimoError Traceback (most recent call last) -""" - struct DecimoError[error_type: String = "DecimoError"](Writable): """Base type for all Decimo errors. @@ -111,9 +106,13 @@ struct DecimoError[error_type: String = "DecimoError"](Writable): """ var file: String + """The source file where the error occurred.""" var function: String + """The function name where the error occurred.""" var message: Optional[String] + """An optional message describing the error.""" var previous_error: Optional[String] + """An optional formatted string of a previous error that caused this one.""" def __init__( out self, @@ -122,6 +121,14 @@ struct DecimoError[error_type: String = "DecimoError"](Writable): message: Optional[String], previous_error: Optional[Error], ): + """Creates a new `DecimoError` with the given context. + + Args: + file: The source file where the error occurred. + function: The function name where the error occurred. + message: An optional message describing the error. + previous_error: An optional previous error that caused this one. + """ self.file = file self.function = function self.message = message @@ -133,6 +140,14 @@ struct DecimoError[error_type: String = "DecimoError"](Writable): ) def write_to[W: Writer](self, mut writer: W): + """Writes a formatted error traceback to a writer. + + Parameters: + W: A type conforming to the `Writer` interface. + + Args: + writer: The writer instance. + """ writer.write("\n") writer.write(("-" * 80)) writer.write("\n") diff --git a/src/decimo/rounding_mode.mojo b/src/decimo/rounding_mode.mojo index 68438588..3d83b8fe 100644 --- a/src/decimo/rounding_mode.mojo +++ b/src/decimo/rounding_mode.mojo @@ -54,12 +54,19 @@ struct RoundingMode(Copyable, ImplicitlyCopyable, Movable, Writable): # alias comptime ROUND_DOWN = Self.down() + """Truncate (toward zero).""" comptime ROUND_HALF_UP = Self.half_up() + """Round away from zero if >= 0.5.""" comptime ROUND_HALF_DOWN = Self.half_down() + """Round toward zero if <= 0.5.""" comptime ROUND_HALF_EVEN = Self.half_even() + """Round to nearest even digit if equidistant (banker's rounding).""" comptime ROUND_UP = Self.up() + """Round away from zero.""" comptime ROUND_CEILING = Self.ceiling() + """Round toward positive infinity.""" comptime ROUND_FLOOR = Self.floor() + """Round toward negative infinity.""" # Internal value var value: Int @@ -68,49 +75,106 @@ struct RoundingMode(Copyable, ImplicitlyCopyable, Movable, Writable): # Static constants for each rounding mode @staticmethod def down() -> Self: - """Truncate (toward zero).""" + """Creates a `RoundingMode` that truncates toward zero. + + Returns: + A `RoundingMode` representing truncation toward zero. + """ return Self(0) @staticmethod def half_up() -> Self: - """Round away from zero if >= 0.5.""" + """Creates a `RoundingMode` that rounds away from zero if >= 0.5. + + Returns: + A `RoundingMode` representing half-up rounding. + """ return Self(1) @staticmethod def half_down() -> Self: - """Round toward zero if <= 0.5.""" + """Creates a `RoundingMode` that rounds toward zero if <= 0.5. + + Returns: + A `RoundingMode` representing half-down rounding. + """ return Self(6) @staticmethod def half_even() -> Self: - """Round to nearest even digit if equidistant (banker's rounding).""" + """Creates a `RoundingMode` that rounds to nearest even digit if equidistant. + + Returns: + A `RoundingMode` representing banker's rounding. + """ return Self(2) @staticmethod def up() -> Self: - """Round away from zero.""" + """Creates a `RoundingMode` that rounds away from zero. + + Returns: + A `RoundingMode` representing round-up. + """ return Self(3) @staticmethod def ceiling() -> Self: - """Round toward positive infinity.""" + """Creates a `RoundingMode` that rounds toward positive infinity. + + Returns: + A `RoundingMode` representing ceiling rounding. + """ return Self(4) @staticmethod def floor() -> Self: - """Round toward negative infinity.""" + """Creates a `RoundingMode` that rounds toward negative infinity. + + Returns: + A `RoundingMode` representing floor rounding. + """ return Self(5) def __init__(out self, value: Int): + """Creates a `RoundingMode` from its internal integer representation. + + Args: + value: The integer code identifying the rounding mode. + """ self.value = value def __eq__(self, other: Self) -> Bool: + """Checks whether two `RoundingMode` values are equal. + + Args: + other: The `RoundingMode` to compare against. + + Returns: + `True` if both rounding modes have the same internal value. + """ return self.value == other.value def __eq__(self, other: String) -> Bool: + """Checks whether this rounding mode matches a string name. + + Args: + other: The rounding mode name to compare against (e.g. "ROUND_DOWN"). + + Returns: + `True` if the string representation of this mode equals `other`. + """ return String(self) == other def write_to[W: Writer](self, mut writer: W): + """Writes the rounding mode name to a writer. + + Parameters: + W: A type conforming to the `Writer` interface. + + Args: + writer: The writer instance. + """ if self == Self.down(): writer.write("ROUND_DOWN") elif self == Self.half_up(): diff --git a/src/decimo/str.mojo b/src/decimo/str.mojo index 82e771ce..8da18506 100644 --- a/src/decimo/str.mojo +++ b/src/decimo/str.mojo @@ -20,7 +20,16 @@ from std.algorithm import vectorize def rjust(s: String, width: Int, fillchar: String = " ") -> String: - """Right-justifies a string by padding with fillchar on the left.""" + """Right-justifies a string by padding with a fill character on the left. + + Args: + s: The string to right-justify. + width: The minimum total width of the resulting string. + fillchar: The character used for padding (defaults to space). + + Returns: + The right-justified string, or the original string if it is already at least `width` characters. + """ var n = len(s) if n >= width: return s @@ -28,7 +37,16 @@ def rjust(s: String, width: Int, fillchar: String = " ") -> String: def ljust(s: String, width: Int, fillchar: String = " ") -> String: - """Left-justifies a string by padding with fillchar on the right.""" + """Left-justifies a string by padding with a fill character on the right. + + Args: + s: The string to left-justify. + width: The minimum total width of the resulting string. + fillchar: The character used for padding (defaults to space). + + Returns: + The left-justified string, or the original string if it is already at least `width` characters. + """ var n = len(s) if n >= width: return s diff --git a/src/decimo/tests.mojo b/src/decimo/tests.mojo index 8923533b..061faa49 100644 --- a/src/decimo/tests.mojo +++ b/src/decimo/tests.mojo @@ -73,13 +73,25 @@ struct TestCase(Copyable, Movable, Writable): """ var a: String + """The first input operand as a numeric string.""" var b: String + """The second input operand as a numeric string (empty for unary tests).""" var expected: String + """The expected output value as a numeric string.""" var description: String + """A human-readable description of the test case.""" def __init__( out self, a: String, b: String, expected: String, description: String ): + """Creates a `TestCase` from the given operands and expected result. + + Args: + a: The first input operand as a numeric string. + b: The second input operand as a numeric string. + expected: The expected output value as a numeric string. + description: A short description of what the test case covers. + """ self.a = a self.b = b self.expected = expected @@ -88,18 +100,36 @@ struct TestCase(Copyable, Movable, Writable): ) def __init__(out self, *, copy: Self): + """Creates a copy of a `TestCase`. + + Args: + copy: The instance to copy from. + """ self.a = copy.a self.b = copy.b self.expected = copy.expected self.description = copy.description def __init__(out self, *, deinit take: Self): + """Moves a `TestCase` into a new instance. + + Args: + take: The instance to move from. + """ self.a = take.a^ self.b = take.b^ self.expected = take.expected^ self.description = take.description^ def write_to[T: Writer](self, mut writer: T): + """Writes a formatted representation of the test case to a writer. + + Parameters: + T: A type conforming to the `Writer` interface. + + Args: + writer: The writer instance. + """ writer.write("TestCase:\n") writer.write(" a: " + self.a + "\n") writer.write(" b: " + self.b + "\n") @@ -116,25 +146,53 @@ struct BenchCase(Copyable, Movable, Writable): """A benchmark case with a name and one or two operands.""" var name: String + """The display name of the benchmark case.""" var a: String + """The first operand as a numeric string.""" var b: String + """The second operand as a numeric string (empty for unary benchmarks).""" def __init__(out self, name: String, a: String, b: String = ""): + """Creates a `BenchCase` with the given name and operands. + + Args: + name: The display name of the benchmark case. + a: The first operand as a numeric string. + b: The second operand as a numeric string (defaults to empty). + """ self.name = name self.a = a self.b = b def __init__(out self, *, copy: Self): + """Creates a copy of a `BenchCase`. + + Args: + copy: The instance to copy from. + """ self.name = copy.name self.a = copy.a self.b = copy.b def __init__(out self, *, deinit take: Self): + """Moves a `BenchCase` into a new instance. + + Args: + take: The instance to move from. + """ self.name = take.name^ self.a = take.a^ self.b = take.b^ def write_to[T: Writer](self, mut writer: T): + """Writes a formatted representation of the benchmark case to a writer. + + Parameters: + T: A type conforming to the `Writer` interface. + + Args: + writer: The writer instance. + """ writer.write( "BenchCase(name='", self.name, @@ -233,7 +291,14 @@ def expand_value(s: String) raises -> String: def parse_file(file_path: String) raises -> TOMLDocument: - """Parse a TOML file and return the TOMLDocument.""" + """Parses a TOML file and returns the parsed document. + + Args: + file_path: The path to the TOML file to parse. + + Returns: + A `TOMLDocument` containing the parsed TOML data. + """ try: return parse_toml_file(file_path) except e: @@ -370,17 +435,35 @@ struct PrecisionLevel(Copyable, Movable): """ var precision: Int + """The number of significant digits for this precision level.""" var iterations: Int + """The number of timing iterations to run at this precision.""" def __init__(out self, precision: Int, iterations: Int): + """Creates a `PrecisionLevel` with the given precision and iteration count. + + Args: + precision: The number of significant digits. + iterations: The number of timing iterations to run. + """ self.precision = precision self.iterations = iterations def __init__(out self, *, copy: Self): + """Creates a copy of a `PrecisionLevel`. + + Args: + copy: The instance to copy from. + """ self.precision = copy.precision self.iterations = copy.iterations def __init__(out self, *, deinit take: Self): + """Moves a `PrecisionLevel` into a new instance. + + Args: + take: The instance to move from. + """ self.precision = take.precision self.iterations = take.iterations diff --git a/src/decimo/toml/parser.mojo b/src/decimo/toml/parser.mojo index 8cffdf79..f85443f0 100644 --- a/src/decimo/toml/parser.mojo +++ b/src/decimo/toml/parser.mojo @@ -37,12 +37,19 @@ struct TOMLValue(Copyable, ImplicitlyCopyable, Movable): """Represents a value in the TOML document.""" var type: TOMLValueType + """The value's TOML type.""" var string_value: String + """The string content when type is `STRING`.""" var int_value: Int + """The integer content when type is `INTEGER`.""" var float_value: Float64 + """The float content when type is `FLOAT`.""" var bool_value: Bool + """The boolean content when type is `BOOLEAN`.""" var array_values: List[TOMLValue] + """The array elements when type is `ARRAY`.""" var table_values: Dict[String, TOMLValue] + """The key-value pairs when type is `TABLE`.""" def __init__(out self): """Initialize an empty TOML value.""" @@ -55,7 +62,11 @@ struct TOMLValue(Copyable, ImplicitlyCopyable, Movable): self.table_values = Dict[String, TOMLValue]() def __init__(out self, string_value: String): - """Initialize a string TOML value.""" + """Initialize a string TOML value. + + Args: + string_value: The string content. + """ self.type = TOMLValueType.STRING self.string_value = string_value self.int_value = 0 @@ -65,7 +76,11 @@ struct TOMLValue(Copyable, ImplicitlyCopyable, Movable): self.table_values = Dict[String, TOMLValue]() def __init__(out self, int_value: Int): - """Initialize an integer TOML value.""" + """Initialize an integer TOML value. + + Args: + int_value: The integer content. + """ self.type = TOMLValueType.INTEGER self.string_value = "" self.int_value = int_value @@ -75,7 +90,11 @@ struct TOMLValue(Copyable, ImplicitlyCopyable, Movable): self.table_values = Dict[String, TOMLValue]() def __init__(out self, float_value: Float64): - """Initialize a float TOML value.""" + """Initialize a float TOML value. + + Args: + float_value: The float content. + """ self.type = TOMLValueType.FLOAT self.string_value = "" self.int_value = 0 @@ -85,7 +104,11 @@ struct TOMLValue(Copyable, ImplicitlyCopyable, Movable): self.table_values = Dict[String, TOMLValue]() def __init__(out self, bool_value: Bool): - """Initialize a boolean TOML value.""" + """Initialize a boolean TOML value. + + Args: + bool_value: The boolean content. + """ self.type = TOMLValueType.BOOLEAN self.string_value = "" self.int_value = 0 @@ -95,6 +118,11 @@ struct TOMLValue(Copyable, ImplicitlyCopyable, Movable): self.table_values = Dict[String, TOMLValue]() def __init__(out self, *, copy: Self): + """Creates a copy of an existing `TOMLValue`. + + Args: + copy: The instance to copy from. + """ self.type = copy.type self.string_value = copy.string_value self.int_value = copy.int_value @@ -104,15 +132,27 @@ struct TOMLValue(Copyable, ImplicitlyCopyable, Movable): self.table_values = copy.table_values.copy() def is_table(self) -> Bool: - """Check if this value is a table.""" + """Checks if this value is a table. + + Returns: + `True` if this value is a table, `False` otherwise. + """ return self.type == TOMLValueType.TABLE def is_array(self) -> Bool: - """Check if this value is an array.""" + """Checks if this value is an array. + + Returns: + `True` if this value is an array, `False` otherwise. + """ return self.type == TOMLValueType.ARRAY def as_string(self) -> String: - """Get the value as a string.""" + """Converts the value to a string representation. + + Returns: + The value as a string, or an empty string for unsupported types. + """ if self.type == TOMLValueType.STRING: return self.string_value elif self.type == TOMLValueType.INTEGER: @@ -125,14 +165,22 @@ struct TOMLValue(Copyable, ImplicitlyCopyable, Movable): return "" def as_int(self) -> Int: - """Get the value as an integer.""" + """Returns the value as an integer. + + Returns: + The integer value, or `0` if the type is not `INTEGER`. + """ if self.type == TOMLValueType.INTEGER: return self.int_value else: return 0 def as_float(self) -> Float64: - """Get the value as a float.""" + """Returns the value as a float. + + Returns: + The float value, or `0.0` if the type is not numeric. + """ if self.type == TOMLValueType.FLOAT: return self.float_value elif self.type == TOMLValueType.INTEGER: @@ -141,20 +189,32 @@ struct TOMLValue(Copyable, ImplicitlyCopyable, Movable): return 0.0 def as_bool(self) -> Bool: - """Get the value as a boolean.""" + """Returns the value as a boolean. + + Returns: + The boolean value, or `False` if the type is not `BOOLEAN`. + """ if self.type == TOMLValueType.BOOLEAN: return self.bool_value else: return False def as_table(self) -> Dict[String, TOMLValue]: - """Get the value as a table dictionary.""" + """Returns the value as a table dictionary. + + Returns: + A copy of the table's key-value pairs, or an empty dictionary. + """ if self.type == TOMLValueType.TABLE: return self.table_values.copy() return Dict[String, TOMLValue]() def as_array(self) -> List[TOMLValue]: - """Get the value as an array.""" + """Returns the value as an array. + + Returns: + A copy of the array elements, or an empty list. + """ if self.type == TOMLValueType.ARRAY: return self.array_values.copy() return List[TOMLValue]() @@ -164,53 +224,122 @@ struct TOMLValueType(Copyable, ImplicitlyCopyable, Movable): """Types of values in TOML.""" comptime NULL = TOMLValueType.null() + """Value type for uninitialized or empty values.""" comptime STRING = TOMLValueType.string() + """Value type for string values.""" comptime INTEGER = TOMLValueType.integer() + """Value type for integer values.""" comptime FLOAT = TOMLValueType.float() + """Value type for floating-point values.""" comptime BOOLEAN = TOMLValueType.boolean() + """Value type for boolean values.""" comptime ARRAY = TOMLValueType.array() + """Value type for array values.""" comptime TABLE = TOMLValueType.table() + """Value type for table values.""" var value: Int + """The underlying integer identifier.""" @staticmethod def null() -> TOMLValueType: + """Creates a `TOMLValueType` representing null. + + Returns: + A `TOMLValueType` for null values. + """ return TOMLValueType(0) @staticmethod def string() -> TOMLValueType: + """Creates a `TOMLValueType` representing a string. + + Returns: + A `TOMLValueType` for string values. + """ return TOMLValueType(1) @staticmethod def integer() -> TOMLValueType: + """Creates a `TOMLValueType` representing an integer. + + Returns: + A `TOMLValueType` for integer values. + """ return TOMLValueType(2) @staticmethod def float() -> TOMLValueType: + """Creates a `TOMLValueType` representing a float. + + Returns: + A `TOMLValueType` for floating-point values. + """ return TOMLValueType(3) @staticmethod def boolean() -> TOMLValueType: + """Creates a `TOMLValueType` representing a boolean. + + Returns: + A `TOMLValueType` for boolean values. + """ return TOMLValueType(4) @staticmethod def array() -> TOMLValueType: + """Creates a `TOMLValueType` representing an array. + + Returns: + A `TOMLValueType` for array values. + """ return TOMLValueType(5) @staticmethod def table() -> TOMLValueType: + """Creates a `TOMLValueType` representing a table. + + Returns: + A `TOMLValueType` for table values. + """ return TOMLValueType(6) def __init__(out self, value: Int): + """Creates a new `TOMLValueType` from an integer identifier. + + Args: + value: The integer identifier for this value type. + """ self.value = value def __eq__(self, other: TOMLValueType) -> Bool: + """Checks equality between two value types. + + Args: + other: The value type to compare against. + + Returns: + `True` if the value types are equal, `False` otherwise. + """ return self.value == other.value def __ne__(self, other: TOMLValueType) -> Bool: + """Checks inequality between two value types. + + Args: + other: The value type to compare against. + + Returns: + `True` if the value types differ, `False` otherwise. + """ return self.value != other.value def to_string(self) -> String: + """Returns the human-readable name of this value type. + + Returns: + A string such as `"STRING"`, `"INTEGER"`, or `"UNKNOWN"`. + """ if self == Self.NULL: return "NULL" elif self == Self.STRING: @@ -233,18 +362,34 @@ struct TOMLDocument(Copyable, Movable): """Represents a parsed TOML document.""" var root: Dict[String, TOMLValue] + """The top-level key-value pairs.""" def __init__(out self): + """Initializes the instance.""" self.root = Dict[String, TOMLValue]() def get(self, key: String) raises -> TOMLValue: - """Get a value from the document.""" + """Retrieves a value from the document by key. + + Args: + key: The key to look up. + + Returns: + The value for `key`, or an empty `TOMLValue` if not found. + """ if key in self.root: return self.root[key] return TOMLValue() def get_table(self, table_name: String) raises -> Dict[String, TOMLValue]: - """Get a table from the document.""" + """Retrieves a table from the document by name. + + Args: + table_name: The name of the table to retrieve. + + Returns: + A copy of the table's key-value pairs, or an empty dictionary. + """ if ( table_name in self.root and self.root[table_name].type == TOMLValueType.TABLE @@ -253,7 +398,14 @@ struct TOMLDocument(Copyable, Movable): return Dict[String, TOMLValue]() def get_array(self, key: String) raises -> List[TOMLValue]: - """Get an array from the document.""" + """Retrieves an array from the document by key. + + Args: + key: The key of the array to retrieve. + + Returns: + A copy of the array elements, or an empty list. + """ if key in self.root and self.root[key].type == TOMLValueType.ARRAY: return self.root[key].array_values.copy() return List[TOMLValue]() @@ -261,7 +413,14 @@ struct TOMLDocument(Copyable, Movable): def get_array_of_tables( self, key: String ) raises -> List[Dict[String, TOMLValue]]: - """Get an array of tables from the document.""" + """Retrieves an array of tables from the document by key. + + Args: + key: The key of the array of tables to retrieve. + + Returns: + A list of table dictionaries, or an empty list. + """ var result = List[Dict[String, TOMLValue]]() if key in self.root: @@ -444,14 +603,26 @@ struct TOMLParser: """Parses TOML source text into a TOMLDocument.""" var tokens: List[Token] + """The list of tokens to parse.""" var pos: Int + """The current position in the token list.""" def __init__(out self, source: String): + """Creates a new `TOMLParser` from a TOML source string. + + Args: + source: The TOML source string to parse. + """ var tokenizer = Tokenizer(source) self.tokens = tokenizer.tokenize() self.pos = 0 def __init__(out self, tokens: List[Token]): + """Creates a new `TOMLParser` from a pre-tokenized token list. + + Args: + tokens: The pre-tokenized token list. + """ self.tokens = tokens.copy() self.pos = 0 @@ -710,7 +881,11 @@ struct TOMLParser: # ---- main parse loop ------------------------------------------------- def parse(mut self) raises -> TOMLDocument: - """Parse the tokens into a TOMLDocument.""" + """Parses the tokens into a `TOMLDocument`. + + Returns: + The parsed `TOMLDocument`. + """ var document = TOMLDocument() var current_path = List[String]() var is_array_of_tables = False @@ -777,13 +952,27 @@ struct TOMLParser: def parse_string(input: String) raises -> TOMLDocument: - """Parse a TOML string into a document.""" + """Parses a TOML string into a document. + + Args: + input: The TOML-formatted string to parse. + + Returns: + The parsed `TOMLDocument`. + """ var parser = TOMLParser(input) return parser.parse() def parse_file(file_path: String) raises -> TOMLDocument: - """Parse a TOML file into a document.""" + """Parses a TOML file into a document. + + Args: + file_path: The path to the TOML file. + + Returns: + The parsed `TOMLDocument`. + """ with open(file_path, "r") as file: content = file.read() diff --git a/src/decimo/toml/tokenizer.mojo b/src/decimo/toml/tokenizer.mojo index fd288506..5520c1e9 100644 --- a/src/decimo/toml/tokenizer.mojo +++ b/src/decimo/toml/tokenizer.mojo @@ -19,22 +19,38 @@ A TOML tokenizer for Mojo, implementing the core TOML v1.0 specification. """ comptime WHITESPACE = " \t" +"""Characters treated as whitespace between tokens.""" comptime COMMENT_START = "#" +"""Character that begins a TOML comment.""" comptime QUOTE = '"' +"""Character for basic (double-quoted) strings.""" comptime LITERAL_QUOTE = "'" +"""Character for literal (single-quoted) strings.""" struct Token(Copyable, Movable): """Represents a token in the TOML document.""" var type: TokenType + """The token's category.""" var value: String + """The token's text content.""" var line: Int + """The line number where this token appears (1-based).""" var column: Int + """The column number where this token starts (1-based).""" def __init__( out self, type: TokenType, value: String, line: Int, column: Int ): + """Creates a new `Token`. + + Args: + type: The token's category. + value: The token's text content. + line: The line number where this token appears. + column: The column number where this token starts. + """ self.type = type self.value = value self.line = line @@ -45,16 +61,30 @@ struct SourcePosition: """Tracks position in the source text.""" var line: Int + """The current line number (1-based).""" var column: Int + """The current column number (1-based).""" var index: Int + """The byte offset in the source string.""" def __init__(out self, line: Int = 1, column: Int = 1, index: Int = 0): + """Creates a new `SourcePosition`. + + Args: + line: The initial line number. + column: The initial column number. + index: The initial byte offset. + """ self.line = line self.column = column self.index = index def advance(mut self, char: String): - """Update position after consuming a character.""" + """Advances the position past the given character. + + Args: + char: The character to advance past. + """ if char == "\n": self.line += 1 self.column = 1 @@ -70,114 +100,250 @@ struct TokenType(Copyable, ImplicitlyCopyable, Movable): # Aliases for TokenType static methods to mimic enum constants comptime KEY = TokenType.key() + """Token type for TOML keys.""" comptime STRING = TokenType.string() + """Token type for string values.""" comptime INTEGER = TokenType.integer() + """Token type for integer values.""" comptime FLOAT = TokenType.float() + """Token type for floating-point values.""" comptime BOOLEAN = TokenType.boolean() + """Token type for boolean values.""" comptime DATETIME = TokenType.datetime() + """Token type for datetime values.""" comptime ARRAY_START = TokenType.array_start() + """Token type for array opening bracket `[`.""" comptime ARRAY_END = TokenType.array_end() + """Token type for array closing bracket `]`.""" comptime TABLE_START = TokenType.table_start() + """Token type for table header opening bracket `[`.""" comptime TABLE_END = TokenType.table_end() + """Token type for table header closing bracket `]`.""" comptime ARRAY_OF_TABLES_START = TokenType.array_of_tables_start() + """Token type for array-of-tables opening `[[`.""" comptime EQUAL = TokenType.equal() + """Token type for the `=` separator.""" comptime COMMA = TokenType.comma() + """Token type for the `,` separator.""" comptime NEWLINE = TokenType.newline() + """Token type for newline characters.""" comptime DOT = TokenType.dot() + """Token type for the `.` separator in dotted keys.""" comptime EOF = TokenType.eof() + """Token type for end of file.""" comptime ERROR = TokenType.error() + """Token type for lexer errors.""" comptime INLINE_TABLE_START = TokenType.inline_table_start() + """Token type for inline table opening brace `{`.""" comptime INLINE_TABLE_END = TokenType.inline_table_end() + """Token type for inline table closing brace `}`.""" # Attributes var value: Int + """The underlying integer identifier.""" # Token type constants (lowercase method names) @staticmethod def key() -> TokenType: + """Creates a `TokenType` representing a TOML key. + + Returns: + A `TokenType` for keys. + """ return TokenType(0) @staticmethod def string() -> TokenType: + """Creates a `TokenType` representing a string value. + + Returns: + A `TokenType` for strings. + """ return TokenType(1) @staticmethod def integer() -> TokenType: + """Creates a `TokenType` representing an integer value. + + Returns: + A `TokenType` for integers. + """ return TokenType(2) @staticmethod def float() -> TokenType: + """Creates a `TokenType` representing a floating-point value. + + Returns: + A `TokenType` for floats. + """ return TokenType(3) @staticmethod def boolean() -> TokenType: + """Creates a `TokenType` representing a boolean value. + + Returns: + A `TokenType` for booleans. + """ return TokenType(4) @staticmethod def datetime() -> TokenType: + """Creates a `TokenType` representing a datetime value. + + Returns: + A `TokenType` for datetimes. + """ return TokenType(5) @staticmethod def array_start() -> TokenType: + """Creates a `TokenType` representing an array opening bracket `[`. + + Returns: + A `TokenType` for array starts. + """ return TokenType(6) @staticmethod def array_end() -> TokenType: + """Creates a `TokenType` representing an array closing bracket `]`. + + Returns: + A `TokenType` for array ends. + """ return TokenType(7) @staticmethod def table_start() -> TokenType: + """Creates a `TokenType` representing a table header opening `[`. + + Returns: + A `TokenType` for table starts. + """ return TokenType(8) @staticmethod def table_end() -> TokenType: + """Creates a `TokenType` representing a table header closing `]`. + + Returns: + A `TokenType` for table ends. + """ return TokenType(9) @staticmethod def array_of_tables_start() -> TokenType: + """Creates a `TokenType` representing an array-of-tables opening `[[`. + + Returns: + A `TokenType` for array-of-tables starts. + """ return TokenType(16) @staticmethod def equal() -> TokenType: + """Creates a `TokenType` representing the `=` separator. + + Returns: + A `TokenType` for equals signs. + """ return TokenType(10) @staticmethod def comma() -> TokenType: + """Creates a `TokenType` representing the `,` separator. + + Returns: + A `TokenType` for commas. + """ return TokenType(11) @staticmethod def newline() -> TokenType: + """Creates a `TokenType` representing a newline character. + + Returns: + A `TokenType` for newlines. + """ return TokenType(12) @staticmethod def dot() -> TokenType: + """Creates a `TokenType` representing the `.` separator in dotted keys. + + Returns: + A `TokenType` for dots. + """ return TokenType(13) @staticmethod def eof() -> TokenType: + """Creates a `TokenType` representing end of file. + + Returns: + A `TokenType` for end of file. + """ return TokenType(14) @staticmethod def error() -> TokenType: + """Creates a `TokenType` representing a lexer error. + + Returns: + A `TokenType` for errors. + """ return TokenType(15) @staticmethod def inline_table_start() -> TokenType: + """Creates a `TokenType` representing an inline table opening brace `{`. + + Returns: + A `TokenType` for inline table starts. + """ return TokenType(17) @staticmethod def inline_table_end() -> TokenType: + """Creates a `TokenType` representing an inline table closing brace `}`. + + Returns: + A `TokenType` for inline table ends. + """ return TokenType(18) # Constructor def __init__(out self, value: Int): + """Creates a new `TokenType` from an integer identifier. + + Args: + value: The integer identifier for this token type. + """ self.value = value # Comparison operators def __eq__(self, other: TokenType) -> Bool: + """Checks equality between two token types. + + Args: + other: The token type to compare against. + + Returns: + `True` if the token types are equal, `False` otherwise. + """ return self.value == other.value def __ne__(self, other: TokenType) -> Bool: + """Checks inequality between two token types. + + Args: + other: The token type to compare against. + + Returns: + `True` if the token types differ, `False` otherwise. + """ return self.value != other.value @@ -185,10 +351,18 @@ struct Tokenizer: """Tokenizes TOML source text.""" var source: String + """The TOML source string to tokenize.""" var position: SourcePosition + """The current position in the source.""" var current_char: String + """The character at the current position.""" def __init__(out self, source: String): + """Creates a new `Tokenizer` for the given source. + + Args: + source: The TOML source string to tokenize. + """ self.source = source self.position = SourcePosition() if len(source) > 0: @@ -523,7 +697,11 @@ struct Tokenizer: return Token(TokenType.KEY, result, start_line, start_column) def next_token(mut self) -> Token: - """Get the next token from the source.""" + """Returns the next token from the source. + + Returns: + The next `Token` from the source. + """ self._skip_whitespace() if not self.current_char: @@ -701,7 +879,11 @@ struct Tokenizer: return token^ def tokenize(mut self) -> List[Token]: - """Tokenize the entire source text.""" + """Tokenizes the entire source text. + + Returns: + A list of all tokens from the source. + """ var tokens = List[Token]() var token = self.next_token() From f86c9ee3abb8cc44cbf2a6029de15028d3958efa Mon Sep 17 00:00:00 2001 From: ZHU Yuhao Date: Wed, 8 Apr 2026 23:05:15 +0200 Subject: [PATCH 2/2] Fix comments --- src/decimo/bigdecimal/bigdecimal.mojo | 10 +++++----- src/decimo/bigint10/bigint10.mojo | 6 +++--- src/decimo/biguint/biguint.mojo | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/decimo/bigdecimal/bigdecimal.mojo b/src/decimo/bigdecimal/bigdecimal.mojo index 9e75314e..346ff00c 100644 --- a/src/decimo/bigdecimal/bigdecimal.mojo +++ b/src/decimo/bigdecimal/bigdecimal.mojo @@ -145,7 +145,7 @@ struct BigDecimal( Args: value: The string to parse (e.g. "123.456" or "1.23E+5"). """ - # The string is normalized with `deciomojo.str.parse_numeric_string()`. + # The string is normalized with `decimo.str.parse_numeric_string()`. self = Self.from_string(value) @implicit @@ -375,7 +375,7 @@ struct BigDecimal( @staticmethod def from_string(value: String) raises -> Self: """Initializes a BigDecimal from a string representation. - The string is normalized with `deciomojo.str.parse_numeric_string()`. + The string is normalized with `decimo.str.parse_numeric_string()`. Args: value: The string representation of the BigDecimal. @@ -775,7 +775,7 @@ struct BigDecimal( W: A type conforming to the `Writer` interface. Args: - writer:: The writer instance. + writer: The writer instance. """ writer.write(self.to_string()) @@ -786,7 +786,7 @@ struct BigDecimal( W: A type conforming to the `Writer` interface. Args: - writer:: The writer instance. + writer: The writer instance. """ writer.write('BigDecimal("', self.to_string(), '")') @@ -1507,7 +1507,7 @@ struct BigDecimal( Args: precision: The number of significant digits for the result. - cache:: The shared math constant cache for ln(2) and ln(1.25). + cache: The shared math constant cache for ln(2) and ln(1.25). Returns: The natural logarithm (base e) of this value. diff --git a/src/decimo/bigint10/bigint10.mojo b/src/decimo/bigint10/bigint10.mojo index 0f74e7aa..48770b80 100644 --- a/src/decimo/bigint10/bigint10.mojo +++ b/src/decimo/bigint10/bigint10.mojo @@ -336,7 +336,7 @@ struct BigInt10( @staticmethod def from_string(value: String) raises -> Self: """Initializes a BigInt10 from a string representation. - The string is normalized with `deciomojo.str.parse_numeric_string()`. + The string is normalized with `decimo.str.parse_numeric_string()`. Args: value: The string representation of the BigInt10. @@ -424,7 +424,7 @@ struct BigInt10( W: A type conforming to the `Writer` interface. Args: - writer:: The writer instance. + writer: The writer instance. """ writer.write('BigInt10("', self.to_string(), '")') @@ -440,7 +440,7 @@ struct BigInt10( W: A type conforming to the `Writer` interface. Args: - writer:: The writer instance. + writer: The writer instance. """ writer.write(self.to_string()) diff --git a/src/decimo/biguint/biguint.mojo b/src/decimo/biguint/biguint.mojo index dfdd0aef..b4f68a08 100644 --- a/src/decimo/biguint/biguint.mojo +++ b/src/decimo/biguint/biguint.mojo @@ -652,7 +652,7 @@ struct BigUInt(Absable, Copyable, IntableRaising, Movable, Writable): @staticmethod def from_string(value: String, ignore_sign: Bool = False) raises -> BigUInt: """Initializes a BigUInt from a string representation. - The string is normalized with `deciomojo.str.parse_numeric_string()`. + The string is normalized with `decimo.str.parse_numeric_string()`. Args: value: The string representation of the BigUInt.