https://github.com/edjcase/motoko_numbers
An extension to numbers in motoko
https://github.com/edjcase/motoko_numbers
Last synced: 5 months ago
JSON representation
An extension to numbers in motoko
- Host: GitHub
- URL: https://github.com/edjcase/motoko_numbers
- Owner: edjCase
- License: mit
- Created: 2022-08-13T22:48:50.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2025-09-06T19:04:39.000Z (10 months ago)
- Last Synced: 2025-09-06T21:21:52.245Z (10 months ago)
- Language: Motoko
- Size: 99.6 KB
- Stars: 3
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Motoko Extended Numbers
[](https://mops.one/xtended-numbers)
[](https://github.com/edjCase/motoko_numbers/blob/main/LICENSE)
A 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.
## Package
### MOPS
```bash
mops add xtended-numbers
```
To set up MOPS package manager, follow the instructions from the [MOPS Site](https://mops.one)
## Quick Start
### Example 1: Number Text Parsing
```motoko
import IntX "mo:xtended-numbers/IntX";
import NatX "mo:xtended-numbers/NatX";
// Parse integers with different formats
let hexValue = IntX.fromTextAdvanced("0xFF", #hex, null);
let binaryValue = IntX.fromTextAdvanced("1010", #binary, null);
let decimalWithSeparator = IntX.fromTextAdvanced("1,000,000", #decimal, ?',');
// Parse natural numbers
let natValue = NatX.fromTextAdvanced("1_000_000", #decimal, ?'_');
switch (hexValue) {
case (?value) Debug.print("Hex 0xFF = " # Int.toText(value));
case null Debug.print("Failed to parse hex value");
};
```
### Example 2: Binary Encoding
```motoko
import IntX "mo:xtended-numbers/IntX";
import Buffer "mo:buffer";
// Encode integer to array
let int32Value : Int32 = 42;
let intBytes = IntX.toInt32Bytes(int32Value, #msb); // Big-endian encoding
Debug.print("Bytes: " # debug_show(intBytes));
```
### Example 3: Binary Encoding to Buffer
```motoko
let list = List.empty();
let buffer = Buffer.fromList(list);
// Encode integer to buffer
IntX.toInt32BytesBuffer(buffer, int32Value, #msb); // Big-endian encoding
Debug.print("Bytes: " # debug_show(List.toArray(list)));
```
### Example 4: Type Conversions
```motoko
import IntX "mo:xtended-numbers/IntX";
import NatX "mo:xtended-numbers/NatX";
// Safe type conversions with overflow protection
let largeInt64 : Int64 = 1000000;
// Convert between different integer sizes
let int32Value = IntX.from64To32(largeInt64); // Traps on overflow
let int16Value = IntX.from32To16(int32Value);
let int8Value = IntX.from16To8(int16Value);
// Convert between signed and unsigned
let natValue = NatX.from64ToNat(Int.abs(largeInt64));
let nat32Value = NatX.from64To32(natValue);
Debug.print("Converted chain: " # Int8.toText(int8Value));
```
### Example 5: Float Precision Conversion
```motoko
import FloatX "mo:xtended-numbers/FloatX";
import Debug "mo:core/Debug";
// Convert standard Float to 16-bit precision
let standardFloat : Float = 3.14159;
let float16 = FloatX.fromFloat(standardFloat, #f16);
// Convert back to standard Float
let backToFloat = FloatX.toFloat(float16);
Debug.print("Original: " # Float.toText(standardFloat));
Debug.print("16-bit precision: " # Float.toText(backToFloat));
// Check for special values
if (FloatX.isNaN(float16)) {
Debug.print("Value is NaN");
} else if (FloatX.isPosInf(float16)) {
Debug.print("Value is positive infinity");
};
```
### Example 6: Hexadecimal Float Representation
```motoko
import FloatX "mo:xtended-numbers/FloatX";
// Convert float to hexadecimal representation
let float : Float = 1.5;
let floatX = FloatX.fromFloat(float, #f32);
// Different hex formatting options
let hex1 = FloatX.toTextHex(floatX, { uppercase = false; exponent = #always });
// Result: "0x1.8p+0"
let hex2 = FloatX.toTextHex(floatX, { uppercase = true; exponent = #omitZero });
// Result: "0X1.8" (exponent omitted since it's 0)
let hex3 = FloatX.toTextHex(floatX, { uppercase = false; exponent = #none });
// Result: "0x1.8" (never show exponent)
// Parse hex float strings
let parsed = FloatX.fromText("0x1.8p+2", #f32);
// Parses: 1.5 * 2^2 = 6.0
```
## API Reference
### FloatX Module
```motoko
// Float precision types
public type FloatPrecision = {#f16; #f32; #f64};
public type FloatX = {
precision: FloatPrecision;
isNegative: Bool;
exponent: ?Int;
mantissa: Nat;
};
// Text formatting options
public type ToTextOptions = {
exponent: {#none; #scientific; #engineering; #auto};
precision: ?Nat; // Null = shortest accurate
};
public type ToTextHexOptions = {
uppercase: Bool; // Use uppercase hex digits (0xFF vs 0xff)
exponent: {#none; #always; #omitZero}; // Control binary exponent display (p notation)
};
// Core conversion functions
public func fromFloat(float: Float, precision: FloatPrecision) : FloatX;
public func toFloat(fX: FloatX) : Float;
// Comparison and validation
public func nearlyEqual(a: Float, b: Float, relativeTolerance: Float, absoluteTolerance: Float): Bool;
public func isNaN(fX: FloatX) : Bool;
public func isPosInf(fX: FloatX) : Bool;
public func isNegInf(fX: FloatX) : Bool;
// Text conversion
public func toText(fX: FloatX) : Text;
public func toTextAdvanced(fX: FloatX, options: ToTextOptions) : Text;
public func toTextHex(fX: FloatX, options: ToTextHexOptions) : Text;
public func fromText(text: Text, precision: FloatPrecision) : ?FloatX;
// Binary encoding
public func toBytes(value: FloatX, encoding: {#lsb; #msb}) : [Nat8];
public func toBytesBuffer(buffer: Buffer.Buffer, value: FloatX, encoding: {#lsb; #msb});
public func fromBytes(bytes: Iter.Iter, precision: {#f16; #f32; #f64}, encoding: {#lsb; #msb}) : ?FloatX;
```
### IntX Module
```motoko
// Text formatting type
public type Format = {#decimal; #hex; #binary; #octal};
// Text conversion
public func toText(value : Int) : Text;
public func toTextAdvanced(value : Int, format : Format) : Text;
public func fromText(value : Text) : ?Int;
public func fromTextAdvanced(value : Text, format : Format, seperator : ?Char) : ?Int;
// Type conversions (examples - full set available)
public func from64To32(value: Int64) : Int32;
public func from32To16(value: Int32) : Int16;
public func from16To8(value: Int16) : Int8;
// Binary encoding
public func toIntBytes(value: Int, encoding: {#signedLEB128; #lsb; #msb}) : [Nat8];
public func toIntBytesBuffer(buffer: Buffer.Buffer, value: Int, encoding: {#signedLEB128; #lsb; #msb});
public func toInt32Bytes(value: Int32, encoding: {#lsb; #msb}) : [Nat8];
public func toInt32BytesBuffer(buffer: Buffer.Buffer, value: Int32, encoding: {#lsb; #msb});
public func fromInt32Bytes(bytes: Iter.Iter, encoding: {#lsb; #msb}) : ?Int32;
```
### NatX Module
```motoko
// Similar API to IntX but for natural numbers
public func toText(value : Nat) : Text;
public func fromText(value : Text) : ?Nat;
public func from64To32(value: Nat64) : Nat32;
public func toNatBytes(value: Nat, encoding: {#unsignedLEB128; #lsb; #msb}) : [Nat8];
public func toNatBytesBuffer(buffer: Buffer.Buffer, value: Nat, encoding: {#unsignedLEB128; #lsb; #msb});
public func toNat32Bytes(value: Nat32, encoding: {#lsb; #msb}) : [Nat8];
public func toNat32BytesBuffer(buffer: Buffer.Buffer, value: Nat32, encoding: {#lsb; #msb});
public func fromNat32Bytes(bytes: Iter.Iter, encoding: {#lsb; #msb}) : ?Nat32;
// ... (full API similar to IntX)
```
## Testing
```bash
mops test
```
## Funding
This 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.
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.