{"id":34552960,"url":"https://github.com/fardream/gen-move-math","last_synced_at":"2026-03-17T14:31:47.993Z","repository":{"id":56707494,"uuid":"523532841","full_name":"fardream/gen-move-math","owner":"fardream","description":"Generate missing math functions for move-lang","archived":false,"fork":false,"pushed_at":"2025-09-09T13:11:39.000Z","size":198,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-09T16:32:23.658Z","etag":null,"topics":["math","move-language"],"latest_commit_sha":null,"homepage":"","language":"Move","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fardream.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":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-08-11T00:08:35.000Z","updated_at":"2025-09-09T13:11:43.000Z","dependencies_parsed_at":"2025-09-09T15:09:42.932Z","dependency_job_id":"c4f6b443-e106-4932-83d1-a4227217d780","html_url":"https://github.com/fardream/gen-move-math","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/fardream/gen-move-math","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fardream%2Fgen-move-math","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fardream%2Fgen-move-math/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fardream%2Fgen-move-math/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fardream%2Fgen-move-math/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fardream","download_url":"https://codeload.github.com/fardream/gen-move-math/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fardream%2Fgen-move-math/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27998473,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-24T02:00:07.193Z","response_time":83,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["math","move-language"],"created_at":"2025-12-24T08:05:30.598Z","updated_at":"2025-12-24T08:05:35.096Z","avatar_url":"https://github.com/fardream.png","language":"Move","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gen-move-math and more_math\n\n`gen-move-math` is a cli to generate missing functionalities for [move](https://github.com/move-language/move), and `more_math` is the code generated with default options.\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/fardream/gen-move-math.svg)](https://pkg.go.dev/github.com/fardream/gen-move-math)\n\n[**Movey Link**](https://www.movey.net/packages/more_math)\n\nFollowing types are currently provided:\n\n- signed integer.\n- double width unsigned integer (u256 and u16).\n- decimal.\n- signed decimal.\n\nAlso provided some math functions for move's native unsigned integers:\n\n- addition with carry (never overflow or abort)\n- subtract with borrow (never underflow or abort)\n- multiplication with carry (never overflow or abort)\n- counting leading zeros\n- square root function calculating (y = floor(sqrt(x)))\n- log 2 calculating log_2 x\n\n## Install/Use Code Generator\n\nTo include the code in your move code, generate the code from the command line into your own package.\n\nPlease install [go](https://go.dev). After installation, simply run the below\n\n```shell\ngo install github.com/fardream/gen-move-math@latest\ngen-move-math # other options\n```\n\nOr without downloading\n\n```shell\ngo run github.com/fardream/gen-move-math@latest # other options\n```\n\nSee [example-use.MD](./example-use.MD) for a detailed instruction.\n\n## Signed Integer Math\n\nVast majority of application can go without signed integers, but occasionally, signed integer can solve some corner cases.\n\n**NOTE**: there is really nothing wrong with represent the signed integer with a boolean and a unsigned integer.\n\nThe implementation contained here is 2's complement.\n\n## Double Width Unsigned\n\nThis is mostly about 256-bit unsigned int (but same methodology can be applied to 16 bit unsigned int too - and once we have 16 bit unsigned int, we can redo the same to get 32 bit unsigned int).\n\nRight now the solution is use two `u128`, one for higher 128 bits, and one for lower 128 bits of the 256-bit unsigned int. The implementation for `add` and `subtract` is straightforward.\n\nIn move, the code aborts when overflow or underflow, so the check for those must be done before calculating.\n\n### Multiplication\n\nIf we can solve `u128` multiplication with possible overflow, we can replicate the strategy for 256 bit unsigend int too.\n\nNow, consider a `u128` two `u64`s - one for higher bits and one for lower bits.\n\nBelow is similar code in rust - however, do note we need to check if the addition needs carry.\n\n```rust\nfn mul_with_overflow(x: u128, y: u128) -\u003e (u128, u128) {\n    const HIGHER_1S: u128 = ((1u128 \u003c\u003c 64) - 1) \u003c\u003c 64;\n    const LOWER_1S: u128 = (1u128\u003c\u003c 64) - 1;\n    let x_hi = (x \u0026 HIGHER_1S) \u003e\u003e 64;\n    let x_lo = x \u0026 LOWER_1S;\n    let y_hi = (y \u0026 HIGHER_1S) \u003e\u003e 64;\n    let y_lo = y \u0026 LOWER_1S;\n\n\n    let x_hi_y_lo = x_hi * y_lo;\n    let x_lo_y_hi = x_lo * y_hi;\n\n    let hi = x_hi * x_hi + (x_hi_y_lo \u003e\u003e 64) + (x_lo_y_hi \u003e\u003e 64);\n    let lo = x_lo * y_lo + (x_hi_y_lo \u003c\u003c 64) + (x_lo_y_hi \u003c\u003c 64);\n\n    (lo, hi)\n}\n```\n\n### Division\n\nIt's trivia to calculate x divided by y if x \u003c= y (which is either 0 or 1), and the remainder is either x or 0.\n\nNow assuming x is greater than y:\n\n1. align x and y leading 1 by left shifting y.\n1. set remainder to x, if remainder is greater than the shifted y, subtract it from remainder, and add 1 shifted by the same size to the result.\n1. left shift the shifted y by 1.\n1. repeat until y is not shifted any more.\n\n```rust\nfn leading_zeros(x: u128) -\u003e u8 {\n    if x == 0 {\n        return 128;\n    }\n    let mut t = (1u128) \u003c\u003c 127;\n    let mut r = 0;\n    loop {\n        if x \u0026 t \u003e 0 {\n            break;\n        }\n        t = t \u003e\u003e 1;\n        r = r + 1;\n    }\n\n    r\n}\n\nfn div_mod(x: u128, y: u128) -\u003e (u128, u128) {\n    let nx = leading_zeros(x);\n    let ny = leading_zeros(y);\n\n    let mut shift = ny - nx;\n\n    let mut current = y \u003c\u003c shift;\n    let mut remainder = x;\n    let mut result = 0;\n\n    loop {\n        if remainder \u003e= current {\n            result += 1u128 \u003c\u003c shift;\n            remainder -= current;\n        }\n\n        if shift == 0 {\n            break;\n        }\n        current = current \u003e\u003e 1;\n        shift = shift - 1;\n    }\n    (result, remainder)\n}\n```\n\n## Decimal\n\nFixed decimals are quite straightforward, only two note:\n\n- need to use double size integers to avoid overflow\n- need to multiply the numerator by 10^decimal before performing the division.\n\n## Square Root\n\nThe method is produced from golang's [`Sqrt`](https://pkg.go.dev/math/big#Int.Sqrt) function for `big.Int`. The method is iterative:\n\n$$\ny = (x + x / y) / 2\n$$\n\n## Log 2\n\nBinary Logarithm algo is based on the method laid out [here](https://en.wikipedia.org/wiki/Binary_logarithm).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffardream%2Fgen-move-math","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffardream%2Fgen-move-math","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffardream%2Fgen-move-math/lists"}