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
42 changes: 28 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

A comprehensive decimal and integer mathematics library for [Mojo](https://www.modular.com/mojo).

**[中文·漢字»](./docs/readme_zht.md)** | **[Repository on GitHub»](https://github.com/forfudan/decimojo)**
**[中文·漢字»](https://zhuyuhao.com/decimojo/docs/readme_zht.html)** | **[Repository on GitHub»](https://github.com/forfudan/decimojo)**

## Overview

Expand All @@ -11,7 +11,7 @@ DeciMojo provides a comprehensive decimal and integer mathematics library for Mo
The core types are:

- A 128-bit fixed-point decimal implementation (`Decimal`) supporting up to 29 significant digits with a maximum of 28 decimal places[^fixed]. It features a complete set of mathematical functions including logarithms, exponentiation, roots, and trigonometric operations.
- A base-10 arbitrary-precision integer type (`BigInt`)[^integer] supporting unlimited digits. It features base-10^9 internal representation and basic arithmetic operations.
- A base-10 arbitrary-precision signed integer type (`BigInt`) and a base-10 arbitrary-precision unsigned integer type (`BigUInt`) supporting unlimited digits[^integer]. It features comprehensive arithmetic operations, comparison functions, and supports extremely large integer calculations efficiently.

The library is expanding to include `BigDecimal` types that support arbitrary precision[^arbitrary], allowing for calculations with unlimited digits and decimal places. These extensions are currently under active development.

Expand All @@ -21,7 +21,7 @@ DeciMojo is available in the [modular-community](https://repo.prefix.dev/modular

From the `magic` CLI, simply run ```magic add decimojo```. This fetches the latest version and makes it immediately available for import.

For projects with a `mojoproject.toml`file, add the dependency ```decimojo = ">=0.1.0"```. Then run `magic install` to download and install the package.
For projects with a `mojoproject.toml`file, add the dependency ```decimojo = ">=0.2.0"```. Then run `magic install` to download and install the package.

For the latest development version, clone the [GitHub repository](https://github.com/forfudan/decimojo) and build the package locally.

Expand Down Expand Up @@ -95,36 +95,49 @@ fn main() raises:
print(Decimal("12.34").to_str_scientific()) # Scientific notation: 1.234E+1
```

[Click here for 8 key examples](./docs/examples.md) highlighting the most important features of the `Decimal` type.
[Click here for 8 key examples](https://zhuyuhao.com/decimojo/docs/examples) highlighting the most important features of the `Decimal` type.

### BigInt Quick Start
Here is a comprehensive quick-start guide showcasing each major function of the `BigInt` type.

```mojo
from decimojo.bigint import BigInt
from decimojo import BigInt, BInt
# BInt is an alias for BigInt

fn main() raises:
# === Construction ===
var a = BigInt("12345678901234567890") # From string
var b = BigInt(12345) # From integer
var b = BInt(12345) # From integer

# === Basic Arithmetic ===
print(a + b) # Addition: 12345678901234580235
print(a - b) # Subtraction: 12345678901234555545
print(a * b) # Multiplication: 152415787814108380241050
print(a.truncate_divide(b)) # Division: 999650944609516

# === Division Operations ===
print(a // b) # Floor division: 999650944609516
print(a.truncate_divide(b)) # Truncate division: 999650944609516
print(a % b) # Modulo: 9615

# === Power Operation ===
print(BInt(2).power(10)) # Power: 1024
print(BInt(2) ** 10) # Power (using ** operator): 1024

# === Comparison ===
print(a > b) # Greater than: True
print(a == BigInt("12345678901234567890")) # Equality: True
print(a == BInt("12345678901234567890")) # Equality: True
print(a.is_zero()) # Check for zero: False

# === Type Conversions ===
print(a.to_str()) # To string: "12345678901234567890"

# === Sign Handling ===
print(-a) # Negation: -12345678901234567890
print(abs(BigInt("-12345678901234567890"))) # Absolute value: 12345678901234567890
print(abs(BInt("-12345678901234567890"))) # Absolute value: 12345678901234567890
print(a.is_negative()) # Check if negative: False

# === Extremely large numbers ===
# 3600 digits // 1800 digits
print(BInt("123456789" * 400) // BInt("987654321" * 200))
```

## Objective
Expand All @@ -139,7 +152,7 @@ This project draws inspiration from several established decimal implementations

DeciMojo combines "Deci" and "Mojo" - reflecting its purpose and implementation language. "Deci" (from Latin "decimus" meaning "tenth") highlights our focus on the decimal numeral system that humans naturally use for counting and calculations.

Although the name emphasizes decimals with fractional parts, DeciMojo embraces the full spectrum of decimal mathematics. Our `BigInt` type, while handling only integers, is designed specifically for the decimal numeral system with its base-10^9 internal representation. This approach offers optimal performance while maintaining human-readable decimal semantics, contrasting with binary-focused libraries. Furthermore, `BigInt` serves as the foundation for our `BigDecimal` implementation, enabling arbitrary-precision calculations across both integer and fractional domains.
Although the name emphasizes decimals with fractional parts, DeciMojo embraces the full spectrum of decimal mathematics. Our `BigInt` type, while handling only integers, is designed specifically for the decimal numeral system with its base-10 internal representation. This approach offers optimal performance while maintaining human-readable decimal semantics, contrasting with binary-focused libraries. Furthermore, `BigInt` serves as the foundation for our `BigDecimal` implementation, enabling arbitrary-precision calculations across both integer and fractional domains.

The name ultimately emphasizes our mission: bringing precise, reliable decimal calculations to the Mojo ecosystem, addressing the fundamental need for exact arithmetic that floating-point representations cannot provide.

Expand All @@ -163,6 +176,7 @@ Rome wasn't built in a day. DeciMojo is currently under active development. For
- Financial calculations with banker's rounding (ROUND_HALF_EVEN).
- High-precision advanced mathematical functions (sqrt, root, ln, exp, log10, power).
- Proper implementation of traits (Absable, Comparable, Floatable, Roundable, etc).
- **BigInt and BigUInt** implementations with complete arithmetic operations, proper division semantics (floor and truncate), and support for arbitrary-precision calculations.

### Make it Fast ⚡ (SIGNIFICANT PROGRESS)

Expand Down Expand Up @@ -200,9 +214,9 @@ If you find DeciMojo useful for your research, consider listing it in your citat
@software{Zhu.2025,
author = {Zhu, Yuhao},
year = {2025},
title = {DeciMojo: A comprehensive decimal mathematics library for Mojo},
title = {A comprehensive decimal and integer mathematics library for Mojo},
url = {https://github.com/forfudan/decimojo},
version = {0.1.0},
version = {0.2.0},
note = {Computer Software}
}
```
Expand All @@ -212,5 +226,5 @@ If you find DeciMojo useful for your research, consider listing it in your citat
This repository and its contributions are licensed under the Apache License v2.0.

[^fixed]: The `Decimal` type can represent values with up to 29 significant digits and a maximum of 28 digits after the decimal point. When a value exceeds the maximum representable value (`2^96 - 1`), DeciMojo either raises an error or rounds the value to fit within these constraints. For example, the significant digits of `8.8888888888888888888888888888` (29 eights total with 28 after the decimal point) exceeds the maximum representable value (`2^96 - 1`) and is automatically rounded to `8.888888888888888888888888889` (28 eights total with 27 after the decimal point). DeciMojo's `Decimal` type is similar to `System.Decimal` (C#/.NET), `rust_decimal` in Rust, `DECIMAL/NUMERIC` in SQL Server, etc.
[^integer]: The BigInt implementation uses a base-10^9 representation for efficient storage and calculations, supporting operations on integers with unlimited precision. It serves both as a standalone arbitrary-precision integer type and as the foundation for our upcoming BigDecimal implementation.
[^integer]: The BigInt implementation uses a base-10 representation for users (maintaining decimal semantics), while internally using an optimized base-10^9 storage system for efficient calculations. This approach balances human-readable decimal operations with high-performance computing. It provides both floor division (round toward negative infinity) and truncate division (round toward zero) semantics, enabling precise handling of division operations with correct mathematical behavior regardless of operand signs.
[^arbitrary]: Built on top of our completed BigInt implementation, BigDecimal will support arbitrary precision for both the integer and fractional parts, similar to `decimal` and `mpmath` in Python, `java.math.BigDecimal` in Java, etc.
64 changes: 64 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# DeciMojo released changelog

This is a list of RELEASED changes for the DeciMojo Package.

## 01/04/2025 (v0.2.0)

Version 0.2.0 marks a significant expansion of DeciMojo with the introduction of `BigInt` and `BigUInt` types, providing unlimited precision integer arithmetic to complement the existing fixed-precision `Decimal` type. Core arithmetic functions for the `Decimal` type have been completely rewritten using Mojo 25.2's `UInt128`, delivering substantial performance improvements. This release also extends mathematical capabilities with advanced operations including logarithms, exponentials, square roots, and n-th roots for the `Decimal` type. The codebase has been reorganized into a more modular structure, enhancing maintainability and extensibility. With comprehensive test coverage, improved documentation in multiple languages, and optimized memory management, v0.2.0 represents a major advancement in both functionality and performance for numerical computing in Mojo.

DeciMojo division performance compared with Python's `decimal` module across versions:

| Division Operation | v0.1.0 vs Python | v0.2.0 vs Python | Improvement |
| --------------------------------- | ---------------- | ---------------- | ----------- |
| Integer division (no remainder) | 0.15× (slower) | 485.88× faster | 3239× |
| Simple decimal division | 0.13× (slower) | 185.77× faster | 1429× |
| Division with repeating decimal | 0.04× (slower) | 12.46× faster | 311× |
| Division by one | 0.15× (slower) | 738.60× faster | 4924× |
| Division of zero | 1820.50× faster | 1866.50× faster | 1.03× |
| Division with negative numbers | 0.11× (slower) | 159.32× faster | 1448× |
| Division by very small number | 0.21× (slower) | 452.75× faster | 2156× |
| High precision division | 0.005× (slower) | 15.19× faster | 3038× |
| Division resulting in power of 10 | 0.21× (slower) | 619.00× faster | 2948× |
| Division of very large numbers | 0.06× (slower) | 582.86× faster | 9714× |

_Note: Benchmarks performed on Darwin 24.3.0, arm processor with Python 3.12.9. The dramatic performance improvements in v0.2.0 come from completely rewriting the division algorithm using Mojo 25.2's UInt128 implementation. While v0.1.0 was generally slower than Python for division operations (except for division of zero), v0.2.0 achieves speedups of 12-1866× depending on the specific scenario._

### ⭐️ New

- Add comprehensive `BigInt` and `BigUInt` implementation with unlimited precision integer arithmetic.
- Implement full arithmetic operations for `BigInt` and `BigUInt`: addition, subtraction, multiplication, division, modulo and power operations.
- Support both floor division (round toward negative infinity) and truncate division (round toward zero) semantics for mathematical correctness.
- Add complete comparison operations for `BigInt` with proper handling of negative values.
- Implement efficient string representation and parsing for `BigInt` and `BigUInt`.
- Add advanced mathematical operations for `Decimal`: square root and n-th root.
- Add logarithm functions for `Decimal`: natural logarithm, base-10 logarithm, and logarithm with arbitrary base.
- Add exponential function and power function with arbitrary exponents for `Decimal`.

### 🦋 Changed

- Completely re-write the core arithmetic functions for `Decimal` type using `UInt128` introduced in Mojo 25.2. This significantly improves the performance of `Decimal` operations.
- Improve memory management system to reduce allocations during calculations.
- Reorganize codebase with modular structure (decimal, arithmetics, comparison, exponential).
- Enhance `Decimal` comparison operators for better handling of edge cases.
- Update internal representation of `Decimal` for better precision handling.

### ❌ Removed

- Remove deprecated legacy string formatting methods.
- Remove redundant conversion functions that were replaced with a more unified API.

### 🛠️ Fixed

- Fix edge cases in division operations with zero and one.
- Correct sign handling in mixed-sign operations for both `Decimal`.
- Fix precision loss in repeated addition/subtraction operations.
- Correct rounding behavior in edge cases for financial calculations.
- Address inconsistencies between operator methods and named functions.

### 📚 Documentation and testing

- Add comprehensive test suite for `BigInt` and `BigUInt` with over 200 test cases covering all operations and edge cases.
- Create detailed API documentation for both `Decimal` and `BigInt`.
- Add performance comparison benchmarks between DeciMojo and Python's decimal/int implementation.
- Update multi-language documentation to include all new functionality (English and Chinese).
- Include clear explanations of division semantics and other potentially confusing numerical concepts.
Loading