Skip to content

Commit 8a17db2

Browse files
authored
[mojo] Update the codebase to Mojo v25.5 nightly (#113)
This pull request updates the codebase to Mojo v25.5 (nightly). ### Dependency and Configuration Updates: * Updated the `pixi.toml` file to increment the version from `0.4.1` to `0.5.0`, switch the `max` dependency to a more flexible version constraint (`>25.4`), and include the `max-nightly` channel in the `channels` list. ### Enhancements to `BigDecimal`: * Added new traits (`AnyType`, `Copyable`, `Movable`, `Representable`) to the `BigDecimal` struct to enhance compatibility and functionality. * Updated various methods in `BigDecimal` to use `Self` instead of `BigDecimal`, improving type consistency and reducing redundancy. This includes methods like `extend_precision`, `normalize`, and comparison operators (`__gt__`, `__lt__`, etc.). ### Enhancements to `BigInt`: * Added new traits (`AnyType`, `Comparable`, `Copyable`, `Movable`) to the `BigInt` struct, aligning it with the enhancements made to `BigDecimal`. * Updated initialization methods (`from_list`, `__init__`) to use `var` for input parameters, reflecting a safer and more flexible approach to handling ownership and mutability. ### Optimizations in `BigUInt` Arithmetic: * Replaced `data` with `_data` for internal word storage in SIMD-based arithmetic methods (e.g., `add_slices_simd`, `subtract_simd`), improving encapsulation and clarity. * Removed unnecessary imports (`time`, `testing`) across multiple files to streamline the codebase. ### Other Improvements: * Changed the `@value` decorator to `@fieldwise_init` in the `Rational` struct to reflect a more appropriate initialization strategy.
1 parent 431d993 commit 8a17db2

File tree

15 files changed

+145
-130
lines changed

15 files changed

+145
-130
lines changed

pixi.toml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
[project]
22
authors = ["ZHU Yuhao 朱宇浩 <[email protected]>"]
3-
channels = ["https://conda.modular.com/max", "https://repo.prefix.dev/modular-community", "conda-forge"]
4-
# channels = ["https://conda.modular.com/max-nightly", "https://conda.modular.com/max", "https://repo.prefix.dev/modular-community", "conda-forge"]
3+
channels = ["https://conda.modular.com/max-nightly", "https://conda.modular.com/max", "https://repo.prefix.dev/modular-community", "conda-forge"]
54
description = "An arbitrary-precision decimal and integer mathematics library for Mojo"
65
license = "Apache-2.0"
76
name = "decimojo"
87
platforms = ["osx-arm64", "linux-64"]
98
readme = "README.md"
10-
version = "0.4.1"
9+
version = "0.5.0"
1110

1211
[dependencies]
13-
max = "==25.4"
12+
max = ">25.4"
1413

1514
[tasks]
1615
# format the code

src/decimojo/bigdecimal/bigdecimal.mojo

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,15 @@ This will be configurable in future when Mojo supports global variables.
4040
"""
4141

4242

43-
@value
4443
struct BigDecimal(
4544
Absable,
45+
AnyType,
4646
Comparable,
47+
Copyable,
4748
FloatableRaising,
4849
IntableRaising,
50+
Movable,
51+
Representable,
4952
Roundable,
5053
Stringable,
5154
Writable,
@@ -167,7 +170,7 @@ struct BigDecimal(
167170

168171
@staticmethod
169172
fn from_raw_components(
170-
owned words: List[UInt32], scale: Int = 0, sign: Bool = False
173+
var words: List[UInt32], scale: Int = 0, sign: Bool = False
171174
) -> Self:
172175
"""**UNSAFE** Creates a BigDecimal from its raw components.
173176
The raw components are words, scale, and sign.
@@ -617,32 +620,32 @@ struct BigDecimal(
617620
# ===------------------------------------------------------------------=== #
618621

619622
@always_inline
620-
fn __gt__(self, other: BigDecimal) -> Bool:
623+
fn __gt__(self, other: Self) -> Bool:
621624
"""Returns whether self is greater than other."""
622625
return decimojo.bigdecimal.comparison.compare(self, other) > 0
623626

624627
@always_inline
625-
fn __ge__(self, other: BigDecimal) -> Bool:
628+
fn __ge__(self, other: Self) -> Bool:
626629
"""Returns whether self is greater than or equal to other."""
627630
return decimojo.bigdecimal.comparison.compare(self, other) >= 0
628631

629632
@always_inline
630-
fn __lt__(self, other: BigDecimal) -> Bool:
633+
fn __lt__(self, other: Self) -> Bool:
631634
"""Returns whether self is less than other."""
632635
return decimojo.bigdecimal.comparison.compare(self, other) < 0
633636

634637
@always_inline
635-
fn __le__(self, other: BigDecimal) -> Bool:
638+
fn __le__(self, other: Self) -> Bool:
636639
"""Returns whether self is less than or equal to other."""
637640
return decimojo.bigdecimal.comparison.compare(self, other) <= 0
638641

639642
@always_inline
640-
fn __eq__(self, other: BigDecimal) -> Bool:
643+
fn __eq__(self, other: Self) -> Bool:
641644
"""Returns whether self equals other."""
642645
return decimojo.bigdecimal.comparison.compare(self, other) == 0
643646

644647
@always_inline
645-
fn __ne__(self, other: BigDecimal) -> Bool:
648+
fn __ne__(self, other: Self) -> Bool:
646649
"""Returns whether self does not equal other."""
647650
return decimojo.bigdecimal.comparison.compare(self, other) != 0
648651

@@ -728,7 +731,7 @@ struct BigDecimal(
728731
fn e(precision: Int) raises -> Self:
729732
"""Returns the mathematical constant e to the specified precision."""
730733
return decimojo.bigdecimal.exponential.exp(
731-
x=BigDecimal(BigUInt.ONE), precision=precision
734+
x=Self(BigUInt.ONE), precision=precision
732735
)
733736

734737
# === Exponentional operations === #
@@ -914,7 +917,7 @@ struct BigDecimal(
914917
"""
915918
return self.coefficient.number_of_digits() - 1 - self.scale
916919

917-
fn extend_precision(self, precision_diff: Int) -> BigDecimal:
920+
fn extend_precision(self, precision_diff: Int) -> Self:
918921
"""Returns a number with additional decimal places (trailing zeros).
919922
This multiplies the coefficient by 10^precision_diff and increases
920923
the scale accordingly, preserving the numeric value.
@@ -933,10 +936,11 @@ struct BigDecimal(
933936
In debug mode, negative `precision_diff` raises an assertion error.
934937
935938
Examples:
939+
936940
```
937-
print(BigDecimal("123.456).scale_up(5)) # Output: 123.45600000
938-
print(BigDecimal("123456").scale_up(3)) # Output: 123456.000
939-
print(BigDecimal("123456").scale_up(-1)) # Output: 123456 (no change)
941+
print(BigDecimal("123.456).extend_precision(5)) # Output: 123.45600000
942+
print(BigDecimal("123456").extend_precision(3)) # Output: 123456.000
943+
print(BigDecimal("123456").extend_precision(-1)) # Output: 123456 (no change)
940944
```
941945
"""
942946
debug_assert(
@@ -949,7 +953,7 @@ struct BigDecimal(
949953
if precision_diff <= 0:
950954
return self
951955

952-
return BigDecimal(
956+
return Self(
953957
decimojo.biguint.arithmetics.multiply_by_power_of_ten(
954958
self.coefficient, precision_diff
955959
),
@@ -974,9 +978,9 @@ struct BigDecimal(
974978
975979
Examples:
976980
```
977-
print(BigDecimal("123.456).scale_up(5)) # Output: 123.45600000
978-
print(BigDecimal("123456").scale_up(3)) # Output: 123456.000
979-
print(BigDecimal("123456").scale_up(-1)) # Output: 123456 (no change)
981+
BigDecimal("123.456).extend_precision_inplace(5) # Output: 123.45600000
982+
BigDecimal("123456").extend_precision_inplace(3) # Output: 123456.000
983+
BigDecimal("123456").extend_precision_inplace(-1) # Output: 123456 (no change)
980984
```
981985
"""
982986
debug_assert(
@@ -1107,15 +1111,15 @@ struct BigDecimal(
11071111
"""Returns True if this number represents zero."""
11081112
return self.coefficient.is_zero()
11091113

1110-
fn normalize(self) raises -> BigDecimal:
1114+
fn normalize(self) raises -> Self:
11111115
"""Removes trailing zeros from coefficient while adjusting scale.
11121116
11131117
Notes:
11141118
11151119
Only call it when necessary. Do not normalize after every operation.
11161120
"""
11171121
if self.coefficient.is_zero():
1118-
return BigDecimal(BigUInt(UInt32(0)), 0, False)
1122+
return Self(BigUInt(UInt32(0)), 0, False)
11191123

11201124
var number_of_digits_to_remove = self.number_of_trailing_zeros()
11211125

@@ -1146,7 +1150,7 @@ struct BigDecimal(
11461150
else: # number_of_remaining_digits_to_remove == 8
11471151
coefficient = coefficient // BigUInt(UInt32(100_000_000))
11481152

1149-
return BigDecimal(
1153+
return Self(
11501154
coefficient,
11511155
self.scale - number_of_digits_to_remove,
11521156
self.sign,

src/decimojo/bigdecimal/constants.mojo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ fn pi(precision: Int) raises -> BigDecimal:
179179
return pi_chudnovsky_binary_split(precision)
180180

181181

182-
@value
182+
@fieldwise_init
183183
struct Rational:
184184
"""Represents a rational number p/q for exact arithmetic."""
185185

src/decimojo/bigint/arithmetics.mojo

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@
1818
Implements basic arithmetic functions for the BigInt type.
1919
"""
2020

21-
import time
22-
import testing
23-
2421
from decimojo.bigint.bigint import BigInt
2522
from decimojo.biguint.biguint import BigUInt
2623
from decimojo.rounding_mode import RoundingMode
@@ -38,8 +35,16 @@ fn add(x1: BigInt, x2: BigInt) raises -> BigInt:
3835
"""
3936
# If one of the numbers is zero, return the other number
4037
if x1.is_zero():
38+
debug_assert[assert_mode="none"](
39+
len(x1.magnitude.words) == 1,
40+
"decimojo.bigint.arithmetics.add(): leading zero words in x1",
41+
)
4142
return x2
4243
if x2.is_zero():
44+
debug_assert[assert_mode="none"](
45+
len(x2.magnitude.words) == 1,
46+
"decimojo.bigint.arithmetics.add(): leading zero words in x2",
47+
)
4348
return x1
4449

4550
# If signs are different, delegate to `subtract`
@@ -82,9 +87,17 @@ fn subtract(x1: BigInt, x2: BigInt) raises -> BigInt:
8287
"""
8388
# If the subtrahend is zero, return the minuend
8489
if x2.is_zero():
90+
debug_assert[assert_mode="none"](
91+
len(x2.magnitude.words) == 1,
92+
"decimojo.bigint.arithmetics.add(): leading zero words in x2",
93+
)
8594
return x1
8695
# If the minuend is zero, return the negated subtrahend
8796
if x1.is_zero():
97+
debug_assert[assert_mode="none"](
98+
len(x1.magnitude.words) == 1,
99+
"decimojo.bigint.arithmetics.add(): leading zero words in x1",
100+
)
88101
return -x2
89102

90103
# If signs are different, delegate to `add`
@@ -126,6 +139,10 @@ fn negative(x: BigInt) -> BigInt:
126139
"""
127140
# If x is zero, return zero
128141
if x.is_zero():
142+
debug_assert[assert_mode="none"](
143+
len(x.magnitude.words) == 1,
144+
"decimojo.bigint.arithmetics.add(): leading zero words in x",
145+
)
129146
return BigInt()
130147

131148
var result = x

src/decimojo/bigint/bigint.mojo

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ mathematical methods that do not implement a trait.
2424
"""
2525

2626
from memory import UnsafePointer
27-
import testing
28-
import time
2927

3028
import decimojo.bigint.arithmetics
3129
import decimojo.bigint.comparison
@@ -37,8 +35,17 @@ import decimojo.str
3735
alias BInt = BigInt
3836

3937

40-
@value
41-
struct BigInt(Absable, IntableRaising, Representable, Stringable, Writable):
38+
struct BigInt(
39+
Absable,
40+
AnyType,
41+
Comparable,
42+
Copyable,
43+
IntableRaising,
44+
Movable,
45+
Representable,
46+
Stringable,
47+
Writable,
48+
):
4249
"""Represents a base-10 arbitrary-precision signed integer.
4350
4451
Notes:
@@ -106,7 +113,7 @@ struct BigInt(Absable, IntableRaising, Representable, Stringable, Writable):
106113
self.magnitude = BigUInt(words)
107114
self.sign = sign
108115

109-
fn __init__(out self, owned *words: UInt32, sign: Bool) raises:
116+
fn __init__(out self, var *words: UInt32, sign: Bool) raises:
110117
"""***UNSAFE!*** Initializes a BigInt from raw components.
111118
It does not check whether the words are invalid.
112119
See `from_words()` for safer initialization.
@@ -175,7 +182,7 @@ struct BigInt(Absable, IntableRaising, Representable, Stringable, Writable):
175182
# ===------------------------------------------------------------------=== #
176183

177184
@staticmethod
178-
fn from_list(owned words: List[UInt32], sign: Bool) raises -> Self:
185+
fn from_list(var words: List[UInt32], sign: Bool) raises -> Self:
179186
"""Initializes a BigInt from a list of UInt32 words safely.
180187
If the list is empty, the BigInt is initialized with value 0.
181188

0 commit comments

Comments
 (0)