{"id":24083345,"url":"https://github.com/mitranim/frac","last_synced_at":"2025-04-30T18:23:20.877Z","repository":{"id":57569633,"uuid":"344936990","full_name":"mitranim/frac","owner":"mitranim","description":"Missing feature of Go stdlib: integers ↔︎ fractional numeric strings, without rounding errors or bignums. Arbitrary fraction precision and radix.","archived":false,"fork":false,"pushed_at":"2023-07-10T09:11:55.000Z","size":9,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-26T06:56:56.288Z","etag":null,"topics":["bignum","decimal","fractional","golang"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mitranim.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2021-03-05T21:20:04.000Z","updated_at":"2023-08-01T09:08:41.000Z","dependencies_parsed_at":"2024-06-20T11:57:44.964Z","dependency_job_id":"ca4e7a7a-e62c-44cb-b48a-14f1f1d64f65","html_url":"https://github.com/mitranim/frac","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Ffrac","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Ffrac/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Ffrac/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Ffrac/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mitranim","download_url":"https://codeload.github.com/mitranim/frac/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251758760,"owners_count":21639106,"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","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":["bignum","decimal","fractional","golang"],"created_at":"2025-01-09T23:56:26.140Z","updated_at":"2025-04-30T18:23:20.855Z","avatar_url":"https://github.com/mitranim.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Overview\n\nMissing feature of the Go standard library: parsing and formatting `int64` as a fractional numeric string, _without any rounding or bignums_, by using a fixed fraction size. Supports arbitrary radixes from 2 to 36.\n\nFor example:\n\n```\n\"123\"     \u003c- frac 2, radix 10 -\u003e 123_00\n\"123\"     \u003c- frac 3, radix 10 -\u003e 123_000\n\n\"123.45\"  \u003c- frac 2, radix 10 -\u003e 123_45\n\"123.45\"  \u003c- frac 3, radix 10 -\u003e 123_450\n\n\"123.456\" \u003c- frac 2, radix 10 -\u003e \u003cerror\u003e\n\"123.456\" \u003c- frac 3, radix 10 -\u003e 123_456\n```\n\nPerformance on 64-bit machines is somewhat comparable to `strconv` and shouldn't be your bottleneck.\n\nSee API docs at https://pkg.go.dev/github.com/mitranim/frac.\n\n## Why\n\n* You use integers for money.\n* You deal with external APIs that use decimal strings for money.\n* You want to avoid rounding errors.\n* You don't want to deal with \"big decimal\" libraries.\n\nThen `frac` is for you!\n\n## Usage\n\nBasic usage:\n\n```golang\nimport \"github.com/mitranim/frac\"\n\nfunc main() {\n  num, err := frac.ParseDec(`-123`, 2)\n  assert(err == nil \u0026\u0026 num == -123_00)\n\n  num, err = frac.ParseDec(`-123.00`, 2)\n  assert(err == nil \u0026\u0026 num == -123_00)\n\n  num, err = frac.ParseDec(`-123.45`, 2)\n  assert(err == nil \u0026\u0026 num == -123_45)\n\n  // Exponent exceeds allotted precision. Conversion is impossible.\n  num, err = frac.ParseDec(`-123.456`, 2)\n  assert(err != nil \u0026\u0026 num == 0)\n}\n\nfunc assert(ok bool) {if !ok {panic(\"unreachable\")}}\n```\n\nImplementing a monetary type:\n\n```golang\nimport \"github.com/mitranim/frac\"\n\ntype Cents int64\n\nfunc (self *Cents) UnmarshalText(input []byte) error {\n  num, err := frac.UnmarshalDec(input, 2)\n  if err != nil {\n    return err\n  }\n  *self = Cents(num)\n  return nil\n}\n\nfunc (self Cents) MarshalText() ([]byte, error) {\n  return frac.AppendDec(nil, int64(self), 2)\n}\n```\n\nThe resulting type `Cents` is an integer, but when decoding and encoding text, it's represented as a fractional with 2 decimal points.\n\n## Known Limitations\n\n* The code is too assembly-like. Kinda like the standard library.\n\n* No special support for unsigned integers.\n\n* When formatting, fractional precision is limited to `64`. (Imagine allocating gigabytes of memory for `0.0...01`.)\n\n## License\n\nhttps://unlicense.org\n\n## Misc\n\nI'm receptive to suggestions. If this library _almost_ satisfies you but needs changes, open an issue or chat me up. Contacts: https://mitranim.com/#contacts\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitranim%2Ffrac","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmitranim%2Ffrac","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitranim%2Ffrac/lists"}