{"id":27401266,"url":"https://github.com/edjcase/motoko_numbers","last_synced_at":"2026-01-20T09:34:52.802Z","repository":{"id":58243199,"uuid":"524524265","full_name":"edjCase/motoko_numbers","owner":"edjCase","description":"An extension to numbers in motoko","archived":false,"fork":false,"pushed_at":"2025-09-06T19:04:39.000Z","size":102,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-06T21:21:52.245Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Motoko","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/edjCase.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-13T22:48:50.000Z","updated_at":"2025-09-06T19:04:43.000Z","dependencies_parsed_at":"2025-09-06T21:05:02.419Z","dependency_job_id":"365b1237-b432-4e90-ad2b-f84cc795a92d","html_url":"https://github.com/edjCase/motoko_numbers","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/edjCase/motoko_numbers","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edjCase%2Fmotoko_numbers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edjCase%2Fmotoko_numbers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edjCase%2Fmotoko_numbers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edjCase%2Fmotoko_numbers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/edjCase","download_url":"https://codeload.github.com/edjCase/motoko_numbers/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edjCase%2Fmotoko_numbers/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28600709,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T08:51:33.170Z","status":"ssl_error","status_checked_at":"2026-01-20T08:51:10.855Z","response_time":117,"last_error":"SSL_read: 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":[],"created_at":"2025-04-14T03:54:35.874Z","updated_at":"2026-01-20T09:34:52.797Z","avatar_url":"https://github.com/edjCase.png","language":"Motoko","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Motoko Extended Numbers\n\n[![MOPS](https://img.shields.io/badge/MOPS-xtended--numbers-blue)](https://mops.one/xtended-numbers)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/edjCase/motoko_numbers/blob/main/LICENSE)\n\nA comprehensive Motoko library that extends the base number functionality with advanced features including 16/32-bit precision floats, number encoding/decoding, text parsing, and type conversions. This library provides robust utilities for working with various number formats and encodings in Motoko applications.\n\n## Package\n\n### MOPS\n\n```bash\nmops add xtended-numbers\n```\n\nTo set up MOPS package manager, follow the instructions from the [MOPS Site](https://mops.one)\n\n## Quick Start\n\n### Example 1: Number Text Parsing\n\n```motoko\nimport IntX \"mo:xtended-numbers/IntX\";\nimport NatX \"mo:xtended-numbers/NatX\";\n\n// Parse integers with different formats\nlet hexValue = IntX.fromTextAdvanced(\"0xFF\", #hex, null);\nlet binaryValue = IntX.fromTextAdvanced(\"1010\", #binary, null);\nlet decimalWithSeparator = IntX.fromTextAdvanced(\"1,000,000\", #decimal, ?',');\n\n// Parse natural numbers\nlet natValue = NatX.fromTextAdvanced(\"1_000_000\", #decimal, ?'_');\n\nswitch (hexValue) {\n  case (?value) Debug.print(\"Hex 0xFF = \" # Int.toText(value));\n  case null Debug.print(\"Failed to parse hex value\");\n};\n```\n\n### Example 2: Binary Encoding\n\n```motoko\nimport IntX \"mo:xtended-numbers/IntX\";\nimport Buffer \"mo:buffer\";\n\n// Encode integer to array\nlet int32Value : Int32 = 42;\nlet intBytes = IntX.toInt32Bytes(int32Value, #msb); // Big-endian encoding\n\nDebug.print(\"Bytes: \" # debug_show(intBytes));\n```\n\n### Example 3: Binary Encoding to Buffer\n\n```motoko\nlet list = List.empty\u003cNat8\u003e();\nlet buffer = Buffer.fromList(list);\n// Encode integer to buffer\nIntX.toInt32BytesBuffer(buffer, int32Value, #msb); // Big-endian encoding\n\nDebug.print(\"Bytes: \" # debug_show(List.toArray(list)));\n```\n\n### Example 4: Type Conversions\n\n```motoko\nimport IntX \"mo:xtended-numbers/IntX\";\nimport NatX \"mo:xtended-numbers/NatX\";\n\n// Safe type conversions with overflow protection\nlet largeInt64 : Int64 = 1000000;\n\n// Convert between different integer sizes\nlet int32Value = IntX.from64To32(largeInt64); // Traps on overflow\nlet int16Value = IntX.from32To16(int32Value);\nlet int8Value = IntX.from16To8(int16Value);\n\n// Convert between signed and unsigned\nlet natValue = NatX.from64ToNat(Int.abs(largeInt64));\nlet nat32Value = NatX.from64To32(natValue);\n\nDebug.print(\"Converted chain: \" # Int8.toText(int8Value));\n```\n\n### Example 5: Float Precision Conversion\n\n```motoko\nimport FloatX \"mo:xtended-numbers/FloatX\";\nimport Debug \"mo:core/Debug\";\n\n// Convert standard Float to 16-bit precision\nlet standardFloat : Float = 3.14159;\nlet float16 = FloatX.fromFloat(standardFloat, #f16);\n\n// Convert back to standard Float\nlet backToFloat = FloatX.toFloat(float16);\nDebug.print(\"Original: \" # Float.toText(standardFloat));\nDebug.print(\"16-bit precision: \" # Float.toText(backToFloat));\n\n// Check for special values\nif (FloatX.isNaN(float16)) {\n  Debug.print(\"Value is NaN\");\n} else if (FloatX.isPosInf(float16)) {\n  Debug.print(\"Value is positive infinity\");\n};\n```\n\n### Example 6: Hexadecimal Float Representation\n\n```motoko\nimport FloatX \"mo:xtended-numbers/FloatX\";\n\n// Convert float to hexadecimal representation\nlet float : Float = 1.5;\nlet floatX = FloatX.fromFloat(float, #f32);\n\n// Different hex formatting options\nlet hex1 = FloatX.toTextHex(floatX, { uppercase = false; exponent = #always });\n// Result: \"0x1.8p+0\"\n\nlet hex2 = FloatX.toTextHex(floatX, { uppercase = true; exponent = #omitZero });\n// Result: \"0X1.8\" (exponent omitted since it's 0)\n\nlet hex3 = FloatX.toTextHex(floatX, { uppercase = false; exponent = #none });\n// Result: \"0x1.8\" (never show exponent)\n\n// Parse hex float strings\nlet parsed = FloatX.fromText(\"0x1.8p+2\", #f32);\n// Parses: 1.5 * 2^2 = 6.0\n```\n\n## API Reference\n\n### FloatX Module\n\n```motoko\n// Float precision types\npublic type FloatPrecision = {#f16; #f32; #f64};\npublic type FloatX = {\n  precision: FloatPrecision;\n  isNegative: Bool;\n  exponent: ?Int;\n  mantissa: Nat;\n};\n\n// Text formatting options\npublic type ToTextOptions = {\n  exponent: {#none; #scientific; #engineering; #auto};\n  precision: ?Nat; // Null = shortest accurate\n};\n\npublic type ToTextHexOptions = {\n  uppercase: Bool; // Use uppercase hex digits (0xFF vs 0xff)\n  exponent: {#none; #always; #omitZero}; // Control binary exponent display (p notation)\n};\n\n// Core conversion functions\npublic func fromFloat(float: Float, precision: FloatPrecision) : FloatX;\npublic func toFloat(fX: FloatX) : Float;\n\n// Comparison and validation\npublic func nearlyEqual(a: Float, b: Float, relativeTolerance: Float, absoluteTolerance: Float): Bool;\npublic func isNaN(fX: FloatX) : Bool;\npublic func isPosInf(fX: FloatX) : Bool;\npublic func isNegInf(fX: FloatX) : Bool;\n\n// Text conversion\npublic func toText(fX: FloatX) : Text;\npublic func toTextAdvanced(fX: FloatX, options: ToTextOptions) : Text;\npublic func toTextHex(fX: FloatX, options: ToTextHexOptions) : Text;\npublic func fromText(text: Text, precision: FloatPrecision) : ?FloatX;\n\n// Binary encoding\npublic func toBytes(value: FloatX, encoding: {#lsb; #msb}) : [Nat8];\npublic func toBytesBuffer(buffer: Buffer.Buffer\u003cNat8\u003e, value: FloatX, encoding: {#lsb; #msb});\npublic func fromBytes(bytes: Iter.Iter\u003cNat8\u003e, precision: {#f16; #f32; #f64}, encoding: {#lsb; #msb}) : ?FloatX;\n```\n\n### IntX Module\n\n```motoko\n// Text formatting type\npublic type Format = {#decimal; #hex; #binary; #octal};\n\n// Text conversion\npublic func toText(value : Int) : Text;\npublic func toTextAdvanced(value : Int, format : Format) : Text;\npublic func fromText(value : Text) : ?Int;\npublic func fromTextAdvanced(value : Text, format : Format, seperator : ?Char) : ?Int;\n\n// Type conversions (examples - full set available)\npublic func from64To32(value: Int64) : Int32;\npublic func from32To16(value: Int32) : Int16;\npublic func from16To8(value: Int16) : Int8;\n\n// Binary encoding\npublic func toIntBytes(value: Int, encoding: {#signedLEB128; #lsb; #msb}) : [Nat8];\npublic func toIntBytesBuffer(buffer: Buffer.Buffer\u003cNat8\u003e, value: Int, encoding: {#signedLEB128; #lsb; #msb});\npublic func toInt32Bytes(value: Int32, encoding: {#lsb; #msb}) : [Nat8];\npublic func toInt32BytesBuffer(buffer: Buffer.Buffer\u003cNat8\u003e, value: Int32, encoding: {#lsb; #msb});\npublic func fromInt32Bytes(bytes: Iter.Iter\u003cNat8\u003e, encoding: {#lsb; #msb}) : ?Int32;\n```\n\n### NatX Module\n\n```motoko\n// Similar API to IntX but for natural numbers\npublic func toText(value : Nat) : Text;\npublic func fromText(value : Text) : ?Nat;\npublic func from64To32(value: Nat64) : Nat32;\npublic func toNatBytes(value: Nat, encoding: {#unsignedLEB128; #lsb; #msb}) : [Nat8];\npublic func toNatBytesBuffer(buffer: Buffer.Buffer\u003cNat8\u003e, value: Nat, encoding: {#unsignedLEB128; #lsb; #msb});\npublic func toNat32Bytes(value: Nat32, encoding: {#lsb; #msb}) : [Nat8];\npublic func toNat32BytesBuffer(buffer: Buffer.Buffer\u003cNat8\u003e, value: Nat32, encoding: {#lsb; #msb});\npublic func fromNat32Bytes(bytes: Iter.Iter\u003cNat8\u003e, encoding: {#lsb; #msb}) : ?Nat32;\n// ... (full API similar to IntX)\n```\n\n## Testing\n\n```bash\nmops test\n```\n\n## Funding\n\nThis library was originally incentivized by [ICDevs](https://ICDevs.org). You can view more about the bounty on the [forum](https://forum.dfinity.org/t/icdevs-org-bounty-18-cbor-and-candid-motoko-parser-3-000/11398) or [website](https://icdevs.org/bounties/2022/02/22/CBOR-and-Candid-Motoko-Parser.html). The bounty was funded by The ICDevs.org community and the award paid to @Gekctek. If you use this library and gain value from it, please consider a [donation](https://icdevs.org/donations.html) to ICDevs.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedjcase%2Fmotoko_numbers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fedjcase%2Fmotoko_numbers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedjcase%2Fmotoko_numbers/lists"}