{"id":48643644,"url":"https://github.com/forfudan/decimo","last_synced_at":"2026-04-28T00:01:12.416Z","repository":{"id":280326397,"uuid":"940482007","full_name":"forfudan/decimo","owner":"forfudan","description":"An arbitrary-precision integer and decimal library for Mojo, inspired by Python's int and Decimal.","archived":false,"fork":false,"pushed_at":"2026-04-24T16:07:32.000Z","size":2320,"stargazers_count":19,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-04-25T18:02:18.477Z","etag":null,"topics":["decimal","math","mojo"],"latest_commit_sha":null,"homepage":"https://github.com/forfudan/decimo","language":"Mojo","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/forfudan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-02-28T08:56:02.000Z","updated_at":"2026-04-24T15:45:16.000Z","dependencies_parsed_at":"2025-06-25T21:25:45.715Z","dependency_job_id":"3d0e19ac-7701-4b50-95a1-58c62f1f9dcd","html_url":"https://github.com/forfudan/decimo","commit_stats":null,"previous_names":["forfudan/decimojo","mojomath/decimojo","forfudan/decimo"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/forfudan/decimo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/forfudan%2Fdecimo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/forfudan%2Fdecimo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/forfudan%2Fdecimo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/forfudan%2Fdecimo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/forfudan","download_url":"https://codeload.github.com/forfudan/decimo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/forfudan%2Fdecimo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32360116,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-27T20:07:02.737Z","status":"ssl_error","status_checked_at":"2026-04-27T20:07:00.910Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["decimal","math","mojo"],"created_at":"2026-04-10T00:00:21.013Z","updated_at":"2026-04-28T00:01:12.366Z","avatar_url":"https://github.com/forfudan.png","language":"Mojo","funding_links":[],"categories":["🗂️ Libraries\u003ca id='libraries'\u003e\u003c/a\u003e"],"sub_categories":["Math"],"readme":"# Decimo (formerly DeciMojo) \u003c!-- omit from toc --\u003e\n\nAn arbitrary-precision integer and decimal library for [Mojo](https://www.modular.com/mojo), inspired by Python's `int` and `Decimal`.\n\n[![Version](https://img.shields.io/github/v/tag/forfudan/decimo?label=version\u0026color=blue)](https://github.com/forfudan/decimo/releases)\n[![Mojo](https://img.shields.io/badge/mojo-0.26.2-orange)](https://docs.modular.com/mojo/manual/)\n[![pixi](https://img.shields.io/badge/pixi%20add-decimo-purple)](https://prefix.dev/channels/modular-community/packages/decimo)\n[![CI](https://img.shields.io/github/actions/workflow/status/forfudan/decimo/run_tests.yaml?branch=main\u0026label=tests)](https://github.com/forfudan/decimo/actions/workflows/run_tests.yaml)\n\n\u003c!-- \n[![License](https://img.shields.io/github/license/forfudan/decimo)](LICENSE)\n[![Stars](https://img.shields.io/github/stars/forfudan/decimo?style=flat)](https://github.com/forfudan/decimo/stargazers)\n[![Issues](https://img.shields.io/github/issues/forfudan/decimo)](https://github.com/forfudan/decimo/issues)\n![Platforms](https://img.shields.io/badge/platform-macOS%20%7C%20Linux-lightgrey)\n[![Last Commit](https://img.shields.io/github/last-commit/forfudan/decimo?color=red)](https://github.com/forfudan/decimo/commits/main)\n--\u003e\n\n\u003c!-- \n[![中文](https://img.shields.io/badge/中文-介紹-red)](https://github.com/forfudan/decimo/blob/main/docs/readme_zht.md)\n[![Changelog](https://img.shields.io/badge/change-log-yellow)](https://github.com/forfudan/decimo/blob/main/docs/changelog.md)\n[![Repository on GitHub](https://img.shields.io/badge/repo-GitHub-black)](https://github.com/forfudan/decimo)\n[![Discord](https://img.shields.io/badge/discord-join-darkblue)](https://discord.gg/3rGH87uZTk)\n--\u003e\n\n## Overview\n\nDecimo provides an arbitrary-precision integer and decimal library for Mojo. It delivers exact calculations for financial modeling, scientific computing, and applications where floating-point approximation errors are unacceptable. Beyond basic arithmetic, the library includes advanced mathematical functions with guaranteed precision.\n\nFor Pythonistas, `decimo.BInt` to Mojo is like `int` to Python, and `decimo.Decimal` to Mojo is like `decimal.Decimal` to Python.\n\nThe core types are[^auxiliary]:\n\n- An arbitrary-precision signed integer type `BInt`[^bigint], which is a Mojo-native equivalent of Python's `int`.\n- An arbitrary-precision decimal implementation (`Decimal`) allowing for calculations with unlimited digits and decimal places[^arbitrary], which is a Mojo-native equivalent of Python's `decimal.Decimal`.\n- A 128-bit fixed-point decimal implementation (`Dec128`) supporting up to 29 significant digits with a maximum of 28 decimal places[^fixed].\n\n| Type      | Other names          | Information                              | Internal representation |\n| --------- | -------------------- | ---------------------------------------- | ----------------------- |\n| `BInt`    | `BigInt`             | Equivalent to Python's `int`             | Base-2^32               |\n| `Decimal` | `BigDecimal`, `BDec` | Equivalent to Python's `decimal.Decimal` | Base-10^9               |\n| `Dec128`  | `Decimal128`         | 128-bit fixed-precision decimal type     | Triple 32-bit words     |\n\n**Decimo** combines \"**Deci**mal\" and \"**Mo**jo\" - reflecting its purpose and implementation language. \"Decimo\" is also a Latin word meaning \"tenth\" and is the root of the word \"decimal\".\n\nA CLI calculator tool, built on top of the Decimo library and powered by [ArgMojo](https://github.com/forfudan/argmojo) (a command-line argument parser library), is also available in this repository. It provides a convenient way to perform high-precision calculations directly from the command line.\n\nThis repository includes a built-in [TOML parser](./docs/readme_toml.md) (`decimo.toml`), a lightweight pure-Mojo implementation supporting TOML v1.0. It parses configuration files and test data, supporting basic types, arrays, and nested tables. While created for Decimo's testing framework, it offers general-purpose structured data parsing with a clean, simple API.\n\n## Installation\n\nDecimo is available in the modular-community `https://repo.prefix.dev/modular-community` package repository. To access this repository, add it to your `channels` list in your `pixi.toml` file:\n\n```toml\nchannels = [\"https://conda.modular.com/max\", \"https://repo.prefix.dev/modular-community\", \"conda-forge\"]\n```\n\nThen, you can install Decimo using any of these methods:\n\n1. From the `pixi` CLI, run the command ```pixi add decimo```. This fetches the latest version and makes it immediately available for import.\n\n1. In the `mojoproject.toml` file of your project, add the following dependency:\n\n    ```toml\n    decimo = \"==0.9.0\"\n    ```\n\n    Then run `pixi install` to download and install the package.\n\n1. For the latest development version in the `main` branch, clone [this GitHub repository](https://github.com/forfudan/decimo) and build the package locally using the command `pixi run package`.\n\nThe following table summarizes the package versions and their corresponding Mojo versions:\n\n| libary     | version | Mojo version  | package manager |\n| ---------- | ------- | ------------- | --------------- |\n| `decimojo` | v0.1.0  | ==25.1        | magic           |\n| `decimojo` | v0.2.0  | ==25.2        | magic           |\n| `decimojo` | v0.3.0  | ==25.2        | magic           |\n| `decimojo` | v0.3.1  | \u003e=25.2, \u003c25.4 | pixi            |\n| `decimojo` | v0.4.x  | ==25.4        | pixi            |\n| `decimojo` | v0.5.0  | ==25.5        | pixi            |\n| `decimojo` | v0.6.0  | ==0.25.7      | pixi            |\n| `decimojo` | v0.7.0  | ==0.26.1      | pixi            |\n| `decimo`   | v0.8.0  | ==0.26.1      | pixi            |\n| `decimo`   | v0.9.0  | ==0.26.2      | pixi            |\n\n## Quick start\n\nYou can start using Decimo by importing the `decimo` module. An easy way to do this is to import everything from the `prelude` module, which provides the most commonly used types.\n\n```mojo\nfrom decimo import *\n```\n\nThis will import the following types or aliases into your namespace:\n\n- `BInt` (alias of `BigInt`): An arbitrary-precision signed integer type, equivalent to Python's `int`.\n- `Decimal` (also available as `BigDecimal` or `BDec`): An arbitrary-precision decimal type, equivalent to Python's `decimal.Decimal`.\n- `Dec128` (alias of `Decimal128`): A 128-bit fixed-precision decimal type.\n- `RoundingMode`: An enumeration for rounding modes.\n- `ROUND_DOWN`, `ROUND_HALF_UP`, `ROUND_HALF_EVEN`, `ROUND_UP`: Constants for common rounding modes.\n\n---\n\nHere are some examples showcasing the arbitrary-precision feature of the `Decimal` type. For some mathematical operations, the default precision (number of significant digits) is set to `28`. You can change the precision by passing the `precision` argument to the function. This default precision will be configurable globally in future when Mojo supports global variables.\n\n```mojo\nfrom decimo.prelude import *\n\n\ndef main() raises:\n    var a = Decimal(\"123456789.123456789\")\n    var b = Decimal(\n        \"1234.56789\"\n    )\n\n    # === Basic Arithmetic === #\n    print(a + b)  # 123458023.691346789\n    print(a - b)  # 123455554.555566789\n    print(a * b)  # 152415787654.32099750190521\n    print(a.true_divide(b + 1))  # 99919.06565608207008357913866\n\n    # === Exponential Functions === #\n    print(a.sqrt(precision=80))\n    # 11111.111066111110969430554981749302328338130654689094538188579359566416821203641\n    print(a.cbrt(precision=80))\n    # 497.93385938415242742001134219007635925452951248903093962731782327785111102410518\n    print(a.root(b, precision=80))\n    # 1.0152058862996527138602610522640944903320735973237537866713119992581006582644107\n    print(a.power(b, precision=80))\n    # 3.3463611024190802340238135400789468682196324482030786573104956727660098625641520E+9989\n    print(a.exp(precision=80))\n    # 1.8612755889649587035842377856492201091251654136588338983610243887893287518637652E+53616602\n    print(a.log(b, precision=80))\n    # 2.6173300266565482999078843564152939771708486260101032293924082259819624360226238\n    print(a.ln(precision=80))\n    # 18.631401767168018032693933348296537542797015174553735308351756611901741276655161\n\n    # === Trigonometric Functions === #\n    print(a.sin(precision=200))\n    # 0.99985093087193092464780008002600992896256609588456\n    #   91036188395766389946401881352599352354527727927177\n    #   79589259132243649550891532070326452232864052771477\n    #   31418817041042336608522984511928095747763538486886\n    print(b.cos(precision=1000))\n    # -0.9969577603867772005841841569997528013669868536239849713029893885930748434064450375775817720425329394\n    #    9756020177557431933434791661179643984869397089102223199519409695771607230176923201147218218258755323\n    #    7563476302904118661729889931783126826250691820526961290122532541861737355873869924820906724540889765\n    #    5940445990824482174517106016800118438405307801022739336016834311018727787337447844118359555063575166\n    #    5092352912854884589824773945355279792977596081915868398143592738704592059567683083454055626123436523\n    #    6998108941189617922049864138929932713499431655377552668020889456390832876383147018828166124313166286\n    #    6004871998201597316078894718748251490628361253685772937806895692619597915005978762245497623003811386\n    #    0913693867838452088431084666963414694032898497700907783878500297536425463212578556546527017688874265\n    #    0785862902484462361413598747384083001036443681873292719322642381945064144026145428927304407689433744\n    #    5821277763016669042385158254006302666602333649775547203560187716156055524418512492782302125286330865\n\n    # === Internal representation of the number === #\n    (\n        Decimal(\n            \"3.141592653589793238462643383279502884197169399375105820974944\"\n        ).power(2, precision=60)\n    ).print_internal_representation()\n    # Internal Representation Details of BigDecimal\n    # ----------------------------------------------\n    # number:         9.8696044010893586188344909998\n    #                 761511353136994072407906264133\n    #                 5\n    # coefficient:    986960440108935861883449099987\n    #                 615113531369940724079062641335\n    # negative:       False\n    # scale:          59\n    # word 0:         62641335\n    # word 1:         940724079\n    # word 2:         113531369\n    # word 3:         99987615\n    # word 4:         861883449\n    # word 5:         440108935\n    # word 6:         986960\n    # ----------------------------------------------\n```\n\n---\n\nHere is a comprehensive quick-start guide showcasing each major function of the `BInt` type.\n\n```mojo\nfrom decimo.prelude import *\n\n\ndef main() raises:\n    # === Construction ===\n    var a = BInt(\"12345678901234567890\")  # From string\n    var b = BInt(12345)  # From integer\n    var c = BInt(\"1991_10,18\")  # From string with separators and spaces\n    print(a, b, c)\n\n    # === Basic Arithmetic ===\n    print(a + b)  # Addition: 12345678901234580235\n    print(a - b)  # Subtraction: 12345678901234555545\n    print(a * b)  # Multiplication: 152415787814108380241050\n\n    # === Division Operations ===\n    print(a // b)  # Floor division: 999650944609516\n    print(a.truncate_divide(b))  # Truncate division: 999650944609516\n    print(a % b)  # Modulo: 9615\n\n    # === Power Operation ===\n    print(BInt(2).power(10))  # Power: 1024\n    print(BInt(2) ** 10)  # Power (using ** operator): 1024\n\n    # === Comparison ===\n    print(a \u003e b)  # Greater than: True\n    print(a == BInt(\"12345678901234567890\"))  # Equality: True\n    print(a.is_zero())  # Check for zero: False\n\n    # === Type Conversions ===\n    print(String(a))  # To string: \"12345678901234567890\"\n\n    # === Sign Handling ===\n    print(-a)  # Negation: -12345678901234567890\n    print(\n        abs(BInt(\"-12345678901234567890\"))\n    )  # Absolute value: 12345678901234567890\n    print(a.is_negative())  # Check if negative: False\n\n    # === Extremely large numbers ===\n    # 3600 digits // 1800 digits\n    print(BInt(\"123456789\" * 400) // BInt(\"987654321\" * 200))\n\n    # === Greatest common divisor ===\n    print(a.gcd(b))  # Greatest common divisor: 15\n    print(a.gcd(c))  # Greatest common divisor: 6\n```\n\n---\n\nHere is a comprehensive quick-start guide showcasing each major function of the `Dec128` type.\n\n```mojo\nfrom decimo.prelude import *\n\ndef main() raises:\n    # === Construction ===\n    var a = Dec128(\"123.45\")                         # From string\n    var b = Dec128(123)                              # From integer\n    var c = Dec128(123, 2)                           # Integer with scale (1.23)\n    var d = Dec128.from_float(3.14159)               # From floating-point\n    \n    # === Basic Arithmetic ===\n    print(a + b)                                     # Addition: 246.45\n    print(a - b)                                     # Subtraction: 0.45\n    print(a * b)                                     # Multiplication: 15184.35\n    print(a / b)                                     # Division: 1.0036585365853658536585365854\n    \n    # === Rounding \u0026 Precision ===\n    print(a.round(1))                                # Round to 1 decimal place: 123.5\n    print(a.quantize(Dec128(\"0.01\")))                # Format to 2 decimal places: 123.45\n    print(a.round(0, RoundingMode.ROUND_DOWN))       # Round down to integer: 123\n    \n    # === Comparison ===\n    print(a \u003e b)                                     # Greater than: True\n    print(a == Dec128(\"123.45\"))                     # Equality: True\n    print(a.is_zero())                               # Check for zero: False\n    print(Dec128(\"0\").is_zero())                     # Check for zero: True\n    \n    # === Type Conversions ===\n    print(Float64(a))                                # To float: 123.45\n    print(a.to_int())                                # To integer: 123\n    print(a.to_str())                                # To string: \"123.45\"\n    print(a.coefficient())                           # Get coefficient: 12345\n    print(a.scale())                                 # Get scale: 2\n    \n    # === Mathematical Functions ===\n    print(Dec128(\"2\").sqrt())                        # Square root: 1.4142135623730950488016887242\n    print(Dec128(\"100\").root(3))                     # Cube root: 4.641588833612778892410076351\n    print(Dec128(\"2.71828\").ln())                    # Natural log: 0.9999993273472820031578910056\n    print(Dec128(\"10\").log10())                      # Base-10 log: 1\n    print(Dec128(\"16\").log(Dec128(\"2\")))             # Log base 2: 3.9999999999999999999999999999\n    print(Dec128(\"10\").exp())                        # e^10: 22026.465794806716516957900645\n    print(Dec128(\"2\").power(10))                     # Power: 1024\n    \n    # === Sign Handling ===\n    print(-a)                                        # Negation: -123.45\n    print(abs(Dec128(\"-123.45\")))                    # Absolute value: 123.45\n    print(Dec128(\"123.45\").is_negative())            # Check if negative: False\n    \n    # === Special Values ===\n    print(Dec128.PI())                               # π constant: 3.1415926535897932384626433833\n    print(Dec128.E())                                # e constant: 2.7182818284590452353602874714\n    print(Dec128.ONE())                              # Value 1: 1\n    print(Dec128.ZERO())                             # Value 0: 0\n    print(Dec128.MAX())                              # Maximum value: 79228162514264337593543950335\n    \n    # === Convenience Methods ===\n    print(Dec128(\"123.400\").is_integer())            # Check if integer: False\n    print(a.number_of_significant_digits())          # Count significant digits: 5\n    print(Dec128(\"12.34\").to_str_scientific())       # Scientific notation: 1.234E+1\n```\n\n## Objective\n\nFinancial calculations and data analysis require precise decimal arithmetic that floating-point numbers cannot reliably provide. As someone working in finance and credit risk model validation, I needed a dependable correctly-rounded, fixed-precision numeric type when migrating my personal projects from Python to Mojo.\n\nSince Mojo currently lacks a native Decimal type in its standard library, I decided to create my own implementation to fill that gap.\n\nThis project draws inspiration from several established decimal implementations and documentation, e.g., [Python built-in `Decimal` type](https://docs.python.org/3/library/decimal.html), [Rust `rust_decimal` crate](https://docs.rs/rust_decimal/latest/rust_decimal/index.html), [Microsoft's `Decimal` implementation](https://learn.microsoft.com/en-us/dotnet/api/system.decimal.getbits?view=net-9.0\u0026redirectedfrom=MSDN#System_Decimal_GetBits_System_Decimal_), [General Decimal Arithmetic Specification](https://speleotrove.com/decimal/decarith.html), etc. Many thanks to these predecessors for their contributions and their commitment to open knowledge sharing.\n\n## Status\n\nRome wasn't built in a day. Decimo is currently under active development. It has successfully progressed through the **\"make it work\"** phase and the **\"make it right\"**, and is now well into the **\"make it fast\"** phase.\n\nThe `BInt` type is fully implemented and optimized. It has been benchmarked against Python's `int` and demonstrates superior performance in most cases.\n\nBug reports and feature requests are welcome! If you encounter issues, please [file them here](https://github.com/forfudan/decimo/issues).\n\n## Tests and benches\n\nAfter cloning the repo onto your local disk, you can:\n\n- Use `pixi run test` to run tests.\n- Use `pixi run bench` to run benchmarks.\n\n## Citation\n\nIf you find Decimo useful, consider listing it in your citations.\n\n```tex\n@software{Zhu.2026,\n    author       = {Zhu, Yuhao},\n    year         = {2026},\n    title        = {Decimo: An arbitrary-precision integer and decimal library for Mojo},\n    url          = {https://github.com/forfudan/decimo},\n    version      = {0.9.0},\n    note         = {Computer Software}\n}\n```\n\n## License\n\nThis repository and its contributions are licensed under the Apache License v2.0.\n\n[^fixed]: The `Decimal128` 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`), Decimo 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). Decimo's `Decimal128` type is similar to `System.Decimal` (C#/.NET), `rust_decimal` in Rust, `DECIMAL/NUMERIC` in SQL Server, etc.\n[^bigint]: The `BigInt` implementation uses a base-2^32 representation with a little-endian format, where the least significant word is stored at index 0. Each word is a `UInt32`, allowing for efficient storage and arithmetic operations on large integers. This design choice optimizes performance for binary computations while still supporting arbitrary precision.\n[^auxiliary]: The auxiliary types include a base-10 arbitrary-precision signed integer type (`BigInt10`) and a base-10 arbitrary-precision unsigned integer type (`BigUInt`) supporting unlimited digits[^bigint10]. `BigUInt` is used as the internal representation for `BigInt10` and `Decimal`.\n[^bigint10]: The BigInt10 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.\n[^arbitrary]: Built on top of our completed BigInt10 implementation, Decimal supports arbitrary precision for both the integer and fractional parts, similar to `decimal` and `mpmath` in Python, `java.math.BigDecimal` in Java, etc.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fforfudan%2Fdecimo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fforfudan%2Fdecimo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fforfudan%2Fdecimo/lists"}