Skip to content

Commit a1a1137

Browse files
authored
[mojo] Update the code to accommodate with Mojo 25.3 (#85)
Update the code to accommodate with Mojo 25.3
1 parent f2930f0 commit a1a1137

18 files changed

Lines changed: 183 additions & 111 deletions

mojoproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ readme = "README.md"
1010
version = "0.3.0"
1111

1212
[dependencies]
13-
max = "==25.2"
13+
max = "==25.3"
1414

1515
[tasks]
1616
# format the code

src/decimojo/bigdecimal/bigdecimal.mojo

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -620,15 +620,20 @@ struct BigDecimal(Absable, Comparable, IntableRaising, Roundable, Writable):
620620
return decimojo.bigdecimal.comparison.min(self, other)
621621

622622
@always_inline
623-
fn root(self, root: Self, precision: Int) raises -> Self:
623+
fn root(self, root: Self, precision: Int = 28) raises -> Self:
624624
"""Returns the root of the BigDecimal number."""
625625
return decimojo.bigdecimal.exponential.root(self, root, precision)
626626

627627
@always_inline
628-
fn sqrt(self, precision: Int) raises -> Self:
628+
fn sqrt(self, precision: Int = 28) raises -> Self:
629629
"""Returns the square root of the BigDecimal number."""
630630
return decimojo.bigdecimal.exponential.sqrt(self, precision)
631631

632+
@always_inline
633+
fn cbrt(self, precision: Int = 28) raises -> Self:
634+
"""Returns the cube root of the BigDecimal number."""
635+
return decimojo.bigdecimal.exponential.cbrt(self, precision)
636+
632637
@always_inline
633638
fn true_divide(self, other: Self, precision: Int) raises -> Self:
634639
"""Returns the result of true division of two BigDecimal numbers.
@@ -798,9 +803,11 @@ struct BigDecimal(Absable, Comparable, IntableRaising, Roundable, Writable):
798803
else:
799804
ndigits = 3
800805
print(
801-
"word {}:{}{}".format(
806+
String("word {}:{}{}")
807+
.format(
802808
i, " " * (10 - ndigits), String(self.coefficient.words[i])
803-
).rjust(9, fillchar="0")
809+
)
810+
.rjust(9, fillchar="0")
804811
)
805812
print("----------------------------------------------")
806813

@@ -866,7 +873,6 @@ struct BigDecimal(Absable, Comparable, IntableRaising, Roundable, Writable):
866873
var number_of_words_to_remove = number_of_digits_to_remove // 9
867874
var number_of_remaining_digits_to_remove = number_of_digits_to_remove % 9
868875

869-
var words: List[UInt32] = List[UInt32]()
870876
words = self.coefficient.words[number_of_words_to_remove:]
871877
var coefficient = BigUInt(words^)
872878

src/decimojo/bigdecimal/exponential.mojo

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,24 @@ from decimojo.bigdecimal.bigdecimal import BigDecimal
2626
from decimojo.rounding_mode import RoundingMode
2727
import decimojo.utility
2828

29+
# ===----------------------------------------------------------------------=== #
30+
# List of functions in this module:
31+
# - power(base: BigDecimal, exponent: BigDecimal, precision: Int) -> BigDecimal
32+
# - integer_power(base: BigDecimal, exponent: BigDecimal, precision: Int) -> BigDecimal
33+
# - root(x: BigDecimal, n: BigDecimal, precision: Int) -> BigDecimal
34+
# - integer_root(x: BigDecimal, n: BigDecimal, precision: Int) -> BigDecimal
35+
# - is_integer_reciprocal_and_return(n: BigDecimal) -> Tuple[Bool, BigDecimal]
36+
# - is_odd_reciprocal(n: BigDecimal) -> Bool
37+
# - sqrt(x: BigDecimal, precision: Int) -> BigDecimal
38+
# - exp(x: BigDecimal, precision: Int) -> BigDecimal
39+
# - exp_taylor_series(x: BigDecimal, minimum_precision: Int) -> BigDecimal
40+
# - ln(x: BigDecimal, precision: Int) -> BigDecimal
41+
# - log(x: BigDecimal, precision: Int) -> BigDecimal
42+
# - log10(x: BigDecimal, precision: Int) -> BigDecimal
43+
# - ln_series_expansion(x: BigDecimal, precision: Int) -> BigDecimal
44+
# - compute_ln2(precision: Int) -> BigDecimal
45+
# - compute_ln1d25(precision: Int) -> BigDecimal
46+
# ===----------------------------------------------------------------------=== #
2947

3048
# ===----------------------------------------------------------------------=== #
3149
# Power and root functions
@@ -561,6 +579,28 @@ fn sqrt(x: BigDecimal, precision: Int) raises -> BigDecimal:
561579
return guess^
562580

563581

582+
fn cbrt(x: BigDecimal, precision: Int) raises -> BigDecimal:
583+
"""Calculate the cube root of a BigDecimal number.
584+
585+
Args:
586+
x: The number to calculate the cube root of.
587+
precision: The desired precision (number of significant digits) of the result.
588+
589+
Returns:
590+
The cube root of x with the specified precision.
591+
592+
Raises:
593+
Error: If x is negative.
594+
"""
595+
596+
result = integer_root(
597+
x,
598+
BigDecimal(coefficient=BigUInt(List[UInt32](3)), scale=0, sign=False),
599+
precision,
600+
)
601+
return result^
602+
603+
564604
# ===----------------------------------------------------------------------=== #
565605
# Exponential functions
566606
# ===----------------------------------------------------------------------=== #

src/decimojo/bigint/bigint.mojo

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -261,9 +261,8 @@ struct BigInt(Absable, IntableRaising, Writable):
261261
The BigInt representation of the string.
262262
"""
263263
var coef: List[UInt8]
264-
var scale: Int
265264
var sign: Bool
266-
coef, scale, sign = decimojo.str.parse_numeric_string(value)
265+
coef, _scale, sign = decimojo.str.parse_numeric_string(value)
267266

268267
# Check if the number is zero
269268
if len(coef) == 1 and coef[0] == UInt8(0):
@@ -620,8 +619,10 @@ struct BigInt(Absable, IntableRaising, Writable):
620619
else:
621620
ndigits = 3
622621
print(
623-
"word {}:{}{}".format(
622+
String("word {}:{}{}")
623+
.format(
624624
i, " " * (10 - ndigits), String(self.magnitude.words[i])
625-
).rjust(9, fillchar="0")
625+
)
626+
.rjust(9, fillchar="0")
626627
)
627628
print("----------------------------------------------")

src/decimojo/biguint/arithmetics.mojo

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,34 @@ from decimojo.biguint.biguint import BigUInt
2525
import decimojo.biguint.comparison
2626
from decimojo.rounding_mode import RoundingMode
2727

28+
# ===----------------------------------------------------------------------=== #
29+
# List of functions in this module:
30+
# add(x1: BigUInt, x2: BigUInt) -> BigUInt
31+
# add_inplace(x1: BigUInt, x2: BigUInt)
32+
# add_inplace_by_1(x: BigUInt) -> None
33+
# subtract(x1: BigUInt, x2: BigUInt) -> BigUInt
34+
# negative(x: BigUInt) -> BigUInt
35+
# absolute(x: BigUInt) -> BigUInt
36+
# multiply(x1: BigUInt, x2: BigUInt) -> BigUInt
37+
# floor_divide(x1: BigUInt, x2: BigUInt) -> BigUInt
38+
# truncate_divide(x1: BigUInt, x2: BigUInt) -> BigUInt
39+
# ceil_divide(x1: BigUInt, x2: BigUInt) -> BigUInt
40+
# floor_modulo(x1: BigUInt, x2: BigUInt) -> BigUInt
41+
# truncate_modulo(x1: BigUInt, x2: BigUInt) -> BigUInt
42+
# ceil_modulo(x1: BigUInt, x2: BigUInt) -> BigUInt
43+
# divmod(x1: BigUInt, x2: BigUInt) -> Tuple[BigUInt, BigUInt]
44+
# scale_up_by_power_of_10(x: BigUInt, n: Int) -> BigUInt
45+
# floor_divide_general(x1: BigUInt, x2: BigUInt) -> BigUInt
46+
# floor_divide_partition(x1: BigUInt, x2: BigUInt) -> BigUInt
47+
# floor_divide_inplace_by_single_word(x1: BigUInt, x2: BigUInt) -> None
48+
# floor_divide_inplace_by_double_words(x1: BigUInt, x2: BigUInt) -> None
49+
# floor_divide_inplace_by_2(x: BigUInt) -> None
50+
# scale_down_by_power_of_10(x: BigUInt, n: Int) -> BigUInt
51+
# estimate_quotient(x1: BigUInt, x2: BigUInt, j: Int, m: Int) -> UInt64
52+
# shift_words_left(x: BigUInt, j: Int) -> BigUInt
53+
# power_of_10(n: Int) -> BigUInt
54+
# ===----------------------------------------------------------------------=== #
55+
2856
# ===----------------------------------------------------------------------=== #
2957
# Arithmetic Operations
3058
# add, subtract, negative, absolute, multiply, floor_divide, modulo
@@ -75,7 +103,7 @@ fn add(x1: BigUInt, x2: BigUInt) raises -> BigUInt:
75103

76104
var carry: UInt32 = 0
77105
var ith: Int = 0
78-
var sum_of_words: UInt32 = 0
106+
var sum_of_words: UInt32
79107

80108
# Add corresponding words from both numbers
81109
while ith < len(x1.words) or ith < len(x2.words):
@@ -102,7 +130,7 @@ fn add(x1: BigUInt, x2: BigUInt) raises -> BigUInt:
102130
return BigUInt(words=words^)
103131

104132

105-
fn add_inplace(mut x1: BigUInt, x2: BigUInt) raises:
133+
fn add_inplace(mut x1: BigUInt, x2: BigUInt) raises -> None:
106134
"""Increments a BigUInt number by another BigUInt number in place.
107135
108136
Args:
@@ -134,7 +162,7 @@ fn add_inplace(mut x1: BigUInt, x2: BigUInt) raises:
134162

135163
var carry: UInt32 = 0
136164
var ith: Int = 0
137-
var sum_of_words: UInt32 = 0
165+
var sum_of_words: UInt32
138166
var x1_len = len(x1.words)
139167

140168
while ith < x1_len or ith < len(x2.words):
@@ -164,7 +192,7 @@ fn add_inplace(mut x1: BigUInt, x2: BigUInt) raises:
164192
return
165193

166194

167-
fn add_inplace_by_1(mut x: BigUInt) raises:
195+
fn add_inplace_by_1(mut x: BigUInt) raises -> None:
168196
"""Increments a BigUInt number by 1."""
169197
var i = 0
170198
while i < len(x.words):
@@ -211,7 +239,7 @@ fn subtract(x1: BigUInt, x2: BigUInt) raises -> BigUInt:
211239
var words = List[UInt32](capacity=max(len(x1.words), len(x2.words)))
212240
var borrow: Int32 = 0
213241
var ith: Int = 0
214-
var difference: Int32 = 0 # Int32 is sufficient for the difference
242+
var difference: Int32 # Int32 is sufficient for the difference
215243

216244
while ith < len(x1.words):
217245
# Subtract the borrow
@@ -294,7 +322,7 @@ fn multiply(x1: BigUInt, x2: BigUInt) raises -> BigUInt:
294322
# x1 = x1[0] + x1[1] * 10^9
295323
# x2 = x2[0] + x2[1] * 10^9
296324
# x1 * x2 = x1[0] * x2[0] + (x1[0] * x2[1] + x1[1] * x2[0]) * 10^9 + x1[1] * x2[1] * 10^18
297-
var carry: UInt64 = 0
325+
var carry: UInt64
298326
for i in range(len(x1.words)):
299327
# Skip if the word is zero
300328
if x1.words[i] == 0:
@@ -769,7 +797,7 @@ fn floor_divide_partition(x1: BigUInt, x2: BigUInt) raises -> BigUInt:
769797
var number_of_words_remainder = len(x1.words) % len(x2.words)
770798
var number_of_words_dividend: Int
771799
var result = x1
772-
result.words.resize(len(x1.words) - number_of_words_remainder)
800+
result.words.resize(len(x1.words) - number_of_words_remainder, UInt32(0))
773801
var remainder = BigUInt(List[UInt32](capacity=len(x2.words)))
774802
for i in range(len(x1.words) - number_of_words_remainder, len(x1.words)):
775803
remainder.words.append(x1.words[i])
@@ -804,7 +832,9 @@ fn floor_divide_partition(x1: BigUInt, x2: BigUInt) raises -> BigUInt:
804832
return result^
805833

806834

807-
fn floor_divide_inplace_by_single_word(mut x1: BigUInt, x2: BigUInt) raises:
835+
fn floor_divide_inplace_by_single_word(
836+
mut x1: BigUInt, x2: BigUInt
837+
) raises -> None:
808838
"""Divides a BigUInt by a single word divisor in-place.
809839
810840
Args:
@@ -826,7 +856,9 @@ fn floor_divide_inplace_by_single_word(mut x1: BigUInt, x2: BigUInt) raises:
826856
x1.remove_leading_empty_words()
827857

828858

829-
fn floor_divide_inplace_by_double_words(mut x1: BigUInt, x2: BigUInt) raises:
859+
fn floor_divide_inplace_by_double_words(
860+
mut x1: BigUInt, x2: BigUInt
861+
) raises -> None:
830862
"""Divides a BigUInt by double-word divisor in-place.
831863
832864
Args:
@@ -846,7 +878,7 @@ fn floor_divide_inplace_by_double_words(mut x1: BigUInt, x2: BigUInt) raises:
846878
var carry = UInt128(0)
847879
if len(x1.words) % 2 == 1:
848880
carry = UInt128(x1.words[-1])
849-
x1.words.resize(len(x1.words) - 1)
881+
x1.words.resize(len(x1.words) - 1, UInt32(0))
850882

851883
for i in range(len(x1.words) - 1, -1, -2):
852884
var dividend = carry * UInt128(1_000_000_000_000_000_000) + UInt128(
@@ -861,7 +893,7 @@ fn floor_divide_inplace_by_double_words(mut x1: BigUInt, x2: BigUInt) raises:
861893
return
862894

863895

864-
fn floor_divide_inplace_by_2(mut x: BigUInt):
896+
fn floor_divide_inplace_by_2(mut x: BigUInt) -> None:
865897
"""Divides a BigUInt by 2 in-place.
866898
867899
Args:
@@ -880,7 +912,7 @@ fn floor_divide_inplace_by_2(mut x: BigUInt):
880912

881913
# Remove leading zeros
882914
while len(x.words) > 1 and x.words[len(x.words) - 1] == 0:
883-
x.words.resize(len(x.words) - 1)
915+
x.words.resize(len(x.words) - 1, UInt32(0))
884916

885917

886918
fn scale_down_by_power_of_10(x: BigUInt, n: Int) raises -> BigUInt:

src/decimojo/biguint/biguint.mojo

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ struct BigUInt(Absable, IntableRaising, Writable):
327327
raise Error(
328328
"Error in `from_string`: The number is not an integer."
329329
)
330-
coef.resize(len(coef) - scale)
330+
coef.resize(len(coef) - scale, UInt8(0))
331331
scale = 0
332332

333333
var number_of_digits = len(coef) - scale
@@ -822,9 +822,9 @@ struct BigUInt(Absable, IntableRaising, Writable):
822822
else:
823823
ndigits = 3
824824
print(
825-
"word {}:{}{}".format(
826-
i, " " * (10 - ndigits), String(self.words[i])
827-
).rjust(9, fillchar="0")
825+
String("word {}:{}{}")
826+
.format(i, " " * (10 - ndigits), String(self.words[i]))
827+
.rjust(9, fillchar="0")
828828
)
829829
print("----------------------------------------------")
830830

@@ -893,10 +893,9 @@ struct BigUInt(Absable, IntableRaising, Writable):
893893
if word_index >= len(self.words):
894894
return 0
895895
var word = self.words[word_index]
896-
var digit: UInt32 = 0
897896
for _ in range(digit_index):
898897
word = word // 10
899-
digit = word % 10
898+
var digit = word % 10
900899
return UInt8(digit)
901900

902901
@always_inline
@@ -941,7 +940,7 @@ struct BigUInt(Absable, IntableRaising, Writable):
941940
fn remove_leading_empty_words(mut self):
942941
"""Removes leading words of 0 from BigUInt's internal representation."""
943942
while len(self.words) > 1 and self.words[-1] == 0:
944-
self.words.resize(len(self.words) - 1)
943+
self.words.resize(len(self.words) - 1, UInt32(0))
945944

946945
@always_inline
947946
fn remove_trailing_digits_with_rounding(

src/decimojo/decimal/arithmetics.mojo

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,6 @@ fn multiply(x1: Decimal, x2: Decimal) raises -> Decimal:
404404
var x1_scale = x1.scale()
405405
var x2_scale = x2.scale()
406406
var combined_scale = x1_scale + x2_scale
407-
"""Combined scale of the two operands."""
408407
var is_negative = x1.is_negative() != x2.is_negative()
409408

410409
# SPECIAL CASE: true one
@@ -510,8 +509,10 @@ fn multiply(x1: Decimal, x2: Decimal) raises -> Decimal:
510509
var prod: UInt128 = UInt128(x1_coef) * UInt128(x2_coef)
511510
if prod > Decimal.MAX_AS_UINT128:
512511
raise Error(
513-
"Error in `multiply()`: The product is {}, which exceeds"
514-
" the capacity of Decimal (2^96-1)".format(prod)
512+
String(
513+
"Error in `multiply()`: The product is {}, which"
514+
" exceeds the capacity of Decimal (2^96-1)"
515+
).format(prod)
515516
)
516517
else:
517518
return Decimal.from_uint128(prod, 0, is_negative)
@@ -520,8 +521,10 @@ fn multiply(x1: Decimal, x2: Decimal) raises -> Decimal:
520521
else:
521522
var prod: UInt256 = UInt256(x1_coef) * UInt256(x2_coef)
522523
raise Error(
523-
"Error in `multiply()`: The product is {}, which exceeds the"
524-
" capacity of Decimal (2^96-1)".format(prod)
524+
String(
525+
"Error in `multiply()`: The product is {}, which exceeds"
526+
" the capacity of Decimal (2^96-1)"
527+
).format(prod)
525528
)
526529

527530
# SPECIAL CASE: Both operands are integers but with scales
@@ -963,13 +966,9 @@ fn divide(x1: Decimal, x2: Decimal) raises -> Decimal:
963966
# 但我們只能算到 1.0000000000000000000000000000_5,
964967
# 在銀行家捨去法中,我們將捨去項爲5時,向上捨去, 保留28位後爲1.0000000000000000000000000000
965968
# 這樣的捨去法是不準確的,所以我們一律在到達餘數非零且捨去項爲5時,向上捨去
966-
var is_exact_division: Bool = False
967-
if rem == 0:
968-
is_exact_division = True
969-
else:
970-
if digit == 5:
971-
# Not exact division, round up the last digit
972-
quot += 1
969+
if (digit == 5) and (rem != 0):
970+
# Not exact division, round up the last digit
971+
quot += 1
973972

974973
var scale_of_quot = step_counter + diff_scale + adjusted_scale
975974

@@ -980,6 +979,12 @@ fn divide(x1: Decimal, x2: Decimal) raises -> Decimal:
980979
var ndigits_quot = decimojo.utility.number_of_digits(quot)
981980
var ndigits_quot_int_part = ndigits_quot - scale_of_quot
982981

982+
print(
983+
String(
984+
"quot: {}, rem: {}, step_counter: {}, scale_of_quot: {}"
985+
).format(quot, rem, step_counter, scale_of_quot)
986+
)
987+
983988
# TODO: 可以考慮先降 scale 再判斷是否超出最大值.
984989
# TODO: 爲降 scale 引入 round_to_remove_last_n_digits 函數
985990
# If quot is within MAX, return the result
@@ -1062,9 +1067,6 @@ fn divide(x1: Decimal, x2: Decimal) raises -> Decimal:
10621067
step_counter += 1
10631068
# Check if division is exact
10641069

1065-
var is_exact_division: Bool = False
1066-
if rem256 == 0:
1067-
is_exact_division = True
10681070
else:
10691071
if digit == 5:
10701072
# Not exact division, round up the last digit

0 commit comments

Comments
 (0)