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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 11 additions & 18 deletions src/decimojo/arithmetics.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -495,8 +495,6 @@ fn multiply(x1: Decimal, x2: Decimal) raises -> Decimal:

# SPECIAL CASE: Both operands are true integers
if x1_scale == 0 and x2_scale == 0:
# print("DEBUG: Both operands are true integers")
# print("DEBUG: combined_num_bits: ", combined_num_bits)
# Small integers, use UInt64 multiplication
if combined_num_bits <= 64:
var prod: UInt64 = UInt64(x1_coef) * UInt64(x2_coef)
Expand Down Expand Up @@ -526,8 +524,12 @@ fn multiply(x1: Decimal, x2: Decimal) raises -> Decimal:
# SPECIAL CASE: Both operands are integers but with scales
# Examples: 123.0 * 456.00
if x1.is_integer() and x2.is_integer():
var x1_integral_part = x1_coef // (UInt128(10) ** UInt128(x1_scale))
var x2_integral_part = x2_coef // (UInt128(10) ** UInt128(x2_scale))
var x1_integral_part = x1_coef // decimojo.utility.power_of_10[
DType.uint128
](x1_scale)
var x2_integral_part = x2_coef // decimojo.utility.power_of_10[
DType.uint128
](x2_scale)
var prod: UInt256 = UInt256(x1_integral_part) * UInt256(
x2_integral_part
)
Expand All @@ -538,8 +540,11 @@ fn multiply(x1: Decimal, x2: Decimal) raises -> Decimal:
var final_scale = min(
Decimal.MAX_NUM_DIGITS - num_digits, combined_scale
)
# Scale up before it overflows
prod = prod * 10**final_scale
# Scale up by adding trailing zeros
prod = prod * decimojo.utility.power_of_10[DType.uint256](
final_scale
)
# If it overflows, remove the last zero
if prod > Decimal.MAX_AS_UINT256:
prod = prod // 10
final_scale -= 1
Expand Down Expand Up @@ -719,11 +724,6 @@ fn true_divide(x1: Decimal, x2: Decimal) raises -> Decimal:
Error: If x2 is zero.
"""

# print("----------------------------------------")
# print("DEBUG divide()")
# print("DEBUG: x1", x1)
# print("DEBUG: x2", x2)

# Treatment for special cases
# 對各類特殊情況進行處理

Expand Down Expand Up @@ -772,12 +772,6 @@ fn true_divide(x1: Decimal, x2: Decimal) raises -> Decimal:

# diff_scale < 0, then times 10 ** (-diff_scale)
else:
# print("DEBUG: x1_coef", x1_coef)
# print("DEBUG: x1_scale", x1_scale)
# print("DEBUG: x2_coef", x2_coef)
# print("DEBUG: x2_scale", x2_scale)
# print("DEBUG: diff_scale", diff_scale)

# If the result can be stored in UInt128
if (
decimojo.utility.number_of_digits(x1_coef) - diff_scale
Expand All @@ -789,7 +783,6 @@ fn true_divide(x1: Decimal, x2: Decimal) raises -> Decimal:
# If the result should be stored in UInt256
else:
var quot = UInt256(x1_coef) * UInt256(10) ** (-diff_scale)
# print("DEBUG: quot", quot)
if quot > Decimal.MAX_AS_UINT256:
raise Error("Error in `true_divide()`: Decimal overflow")
else:
Expand Down
2 changes: 1 addition & 1 deletion src/decimojo/decimal.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -1045,7 +1045,7 @@ struct Decimal(

# Otherwise, get the integer part by dividing by 10^scale
else:
res = self.coefficient() // 10 ** UInt128(self.scale())
res = self.coefficient() // UInt128(10) ** UInt128(self.scale())

return res

Expand Down
136 changes: 68 additions & 68 deletions src/decimojo/utility.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -633,74 +633,74 @@ fn number_of_bits[dtype: DType, //](owned value: Scalar[dtype]) -> Int:
# ===----------------------------------------------------------------------=== #


# Module-level cache for powers of 10
var _power_of_10_as_uint128_cache = List[UInt128]()
var _power_of_10_as_uint256_cache = List[UInt256]()


# Initialize with the first value
@always_inline
fn _init_power_of_10_as_uint128_cache():
if len(_power_of_10_as_uint128_cache) == 0:
_power_of_10_as_uint128_cache.append(1) # 10^0 = 1


@always_inline
fn _init_power_of_10_as_uint256_cache():
if len(_power_of_10_as_uint256_cache) == 0:
_power_of_10_as_uint256_cache.append(1) # 10^0 = 1


@always_inline
fn power_of_10_as_uint128(n: Int) raises -> UInt128:
"""
Returns 10^n using cached values when available.
"""

# Check for negative exponent
if n < 0:
raise Error(
"power_of_10() requires non-negative exponent, got {}".format(n)
)

# Initialize cache if needed
if len(_power_of_10_as_uint128_cache) == 0:
_init_power_of_10_as_uint128_cache()

# Extend cache if needed
while len(_power_of_10_as_uint128_cache) <= n:
var next_power = _power_of_10_as_uint128_cache[
len(_power_of_10_as_uint128_cache) - 1
] * 10
_power_of_10_as_uint128_cache.append(next_power)

return _power_of_10_as_uint128_cache[n]


@always_inline
fn power_of_10_as_uint256(n: Int) raises -> UInt256:
"""
Returns 10^n using cached values when available.
"""

# Check for negative exponent
if n < 0:
raise Error(
"power_of_10() requires non-negative exponent, got {}".format(n)
)

# Initialize cache if needed
if len(_power_of_10_as_uint256_cache) == 0:
_init_power_of_10_as_uint256_cache()

# Extend cache if needed
while len(_power_of_10_as_uint256_cache) <= n:
var next_power = _power_of_10_as_uint256_cache[
len(_power_of_10_as_uint256_cache) - 1
] * 10
_power_of_10_as_uint256_cache.append(next_power)

return _power_of_10_as_uint256_cache[n]
# # Module-level cache for powers of 10
# var _power_of_10_as_uint128_cache = List[UInt128]()
# var _power_of_10_as_uint256_cache = List[UInt256]()


# # Initialize with the first value
# @always_inline
# fn _init_power_of_10_as_uint128_cache():
# if len(_power_of_10_as_uint128_cache) == 0:
# _power_of_10_as_uint128_cache.append(1) # 10^0 = 1


# @always_inline
# fn _init_power_of_10_as_uint256_cache():
# if len(_power_of_10_as_uint256_cache) == 0:
# _power_of_10_as_uint256_cache.append(1) # 10^0 = 1


# @always_inline
# fn power_of_10_as_uint128(n: Int) raises -> UInt128:
# """
# Returns 10^n using cached values when available.
# """

# # Check for negative exponent
# if n < 0:
# raise Error(
# "power_of_10() requires non-negative exponent, got {}".format(n)
# )

# # Initialize cache if needed
# if len(_power_of_10_as_uint128_cache) == 0:
# _init_power_of_10_as_uint128_cache()

# # Extend cache if needed
# while len(_power_of_10_as_uint128_cache) <= n:
# var next_power = _power_of_10_as_uint128_cache[
# len(_power_of_10_as_uint128_cache) - 1
# ] * 10
# _power_of_10_as_uint128_cache.append(next_power)

# return _power_of_10_as_uint128_cache[n]


# @always_inline
# fn power_of_10_as_uint256(n: Int) raises -> UInt256:
# """
# Returns 10^n using cached values when available.
# """

# # Check for negative exponent
# if n < 0:
# raise Error(
# "power_of_10() requires non-negative exponent, got {}".format(n)
# )

# # Initialize cache if needed
# if len(_power_of_10_as_uint256_cache) == 0:
# _init_power_of_10_as_uint256_cache()

# # Extend cache if needed
# while len(_power_of_10_as_uint256_cache) <= n:
# var next_power = _power_of_10_as_uint256_cache[
# len(_power_of_10_as_uint256_cache) - 1
# ] * 10
# _power_of_10_as_uint256_cache.append(next_power)

# return _power_of_10_as_uint256_cache[n]


@always_inline
Expand Down
Loading