{"id":"dekkonot/int64","name":"int64","scope":"dekkonot","platform":"roblox","description":"Implementation of unsigned 64-bit integers in pure Luau.","version":"1.0.1","latest":"1.0.1","versions":["1.0.0","1.0.1"],"license":"MIT","licenseRating":"safe","licenseCaveats":[],"licenseVerified":true,"dependencies":{},"integrity":"50a16e9c5fb528f8410115777ad84f2fac66d5abba7d0d06d60a9d62078d42c7","likes":0,"downloads":0,"install":"forest install dekkonot/int64","url":"https://forest.dev/p/roblox/dekkonot/int64","files":"https://api.forest.dev/ai/package/roblox/dekkonot/int64/files","readme":"# Int64 Luau\r\n\r\n[![Tests](https://github.com/Dekkonot/int64-luau/actions/workflows/test.yml/badge.svg)](https://github.com/Dekkonot/int64-luau/actions/workflows/test.yml)\r\n\r\nAvailable on:\r\n\r\n-   [Wally](https://wally.run/) as `dekkonot/int64`\r\n-   [npm](https://www.npmjs.com/) as `@dekkonot/int64`\r\n\r\nImplementation of arithmetic and bitwise operations for **unsigned** 64-bit integers in pure Luau. Utilizes `vector` objects to pack the integers efficiently, meaning it avoids expensive table accesses and allocations.\r\n\r\nMajor features:\r\n\r\n-   Arithmetic (addition, subtraction, mutiplication, division, modulo, and exponentiation)\r\n-   Bitwise operations (everything implemented in `bit32` as of this time except for `replace`/`extract`)\r\n-   Convenience functions for converting to and from other forms of data (hex strings, buffers, etc)\r\n\r\nThis does not implement `math` library functionality! Implementations of things like `math.random` are far beyond scope for this library, and implementation of things like `math.sin` are prohibitively complex and incredibly slow. It would also be very difficult to write tests for these that were appropriately exhaustive and it's irresponsible to release them into the world without tests.\r\n\r\nThis module is made as fast as is reasonably possible. However, they are still a fair bit slower than native integers; this will hopefully not be a surprise. You should expect very good performance, but it's possible that depending upon your use case storing two 32-bit integers and operating on them will be faster.\r\n\r\nIf you wish to contribute to this module, whether it be through optimizations or new functionality, please open a pull request.\r\n\r\n## API\r\n\r\n| [Constructors](#constructors)           | [Destructors](#destructors)           | [Constants](#constants) |\r\n| :-------------------------------------- | :------------------------------------ | :---------------------- |\r\n| [`from_f64`](#from_f64)                 | [`to_f64`](#to_f64)                   | [`ZERO`](#ZERO)         |\r\n| [`from_dec_string`](#from_dec_string)   | [`to_dec_string`](#to_dec_string)     | [`ONE`](#ONE)           |\r\n| [`from_pair`](#from_pair)               | [`to_pair`](#to_pair)                 | [`TWO`](#TWO)           |\r\n| [`from_u32`](#from_u32)                 | [`to_quartet`](#to_quartet)           | [`MAX`](#MAX)           |\r\n| [`from_buffer`](#from_buffer)           | [`to_buffer`](#to_buffer)             | [`MAX_U32`](#MAX_U32)   |\r\n| [`from_byte_string`](#from_byte_string) | [`write_to_buffer`](#write_to_buffer) | [`MAX_F64`](#MAX_F64)   |\r\n|                                         | [`to_byte_string`](#to_byte_string)   | [`MAX_F32`](#MAX_F32)   |\r\n|                                         | [`to_hex_string`](#to_hex_string)     |                         |\r\n|                                         | [`to_bin_string`](#to_bin_string)     |                         |\r\n\r\n| [Logical](#logical)     | [Arithmetic](#arithmetic) | [Bitwise](#bitwise)     |\r\n| :---------------------- | :------------------------ | :---------------------- |\r\n| [`gt`](#gt)             | [`add`](#add)             | [`band`](#band)         |\r\n| [`gt_equal`](#gt_equal) | [`sub`](#sub)             | [`bor`](#bor)           |\r\n| [`lt`](#lt)             | [`mult`](#mult)           | [`bxor`](#bxor)         |\r\n| [`lt_equal`](#lt_equal) | [`div`](#div)             | [`bnot`](#bnot)         |\r\n|                         | [`pow`](#pow)             | [`lshift`](#lshift)     |\r\n|                         |                           | [`rshift`](#rshift)     |\r\n|                         |                           | [`arshift`](#arshift)   |\r\n|                         |                           | [`lrotate`](#lrotate)   |\r\n|                         |                           | [`rrotate`](#rrotate)   |\r\n|                         |                           | [`countlz`](#countlz)   |\r\n|                         |                           | [`countrz`](#countrz)   |\r\n|                         |                           | [`btest`](#btest)       |\r\n|                         |                           | [`byteswap`](#byteswap) |\r\n\r\n### Constructors\r\n\r\n#### `from_f64`\r\n\r\n```luau\r\nint64.from_f64(f64: number): vector\r\n```\r\n\r\nConstructs a 64-bit integer from the passed `f64`. Put more plainly, converts a normal Luau number to a 64-bit integer.\r\n\r\nThe number is truncated into an integer first. Note that Luau numbers cannot accurately represent integers past `2 ^ 53`.\r\n\r\n#### `from_dec_string`\r\n\r\n```luau\r\nint64.from_dec_string(str: string): vector\r\n```\r\n\r\nReturns the provided value parsed as a 64-bit integer. Expects the provided string to contain only the digits 0-9 and will error if it does not.\r\n\r\nLeading zeros are accepted and parsed appropriately.\r\n\r\nDue to the implementation, the resulting integer will wrap around if it is too large to fit in a 64-bit integer rather than erroring.\r\n\r\n#### `from_pair`\r\n\r\n```luau\r\nint64.from_pair(most: number, least: number): vector\r\n```\r\n\r\nConstructs a 64-bit integer from the passed `u32` values.\r\n\r\nThe provided `most` value fills the upper 32 bits of the integer, and the provided `least` value fills the lower 32-bits.\r\n\r\n#### `from_u32`\r\n\r\n```luau\r\nint64.from_u32(u32: number): vector\r\n```\r\n\r\nConstructs a 64-bit integer from the passed `u32`.\r\n\r\nThis number is truncated in a 32-bit integer, even if it is larger than the max value.\r\n\r\n#### `from_buffer`\r\n\r\n```luau\r\nint64.from_buffer(buf: buffer, offset: number?): vector\r\n```\r\n\r\nReads a `u64` from the provided buffer. If offset is provided, reads from that spot in the buffer. Otherwise, reads from the beginning.\r\n\r\nThis function reads a little-endian value from the buffer.\r\n\r\n#### `from_byte_string`\r\n\r\n```luau\r\nint64.from_byte_string(str: string, offset: number?): vector\r\n```\r\n\r\nReads a `u64` from the provided string. If offset is provided, reads from that point in the string. Otherwise starts at the beginning.\r\n\r\nThis function reads a little-endian value from the string.\r\n\r\n### Destructors\r\n\r\n#### `to_f64`\r\n\r\n```luau\r\nint64.to_f64(u64: vector): number\r\n```\r\n\r\nConverts the provided `u64` to an `f64` (or put plainly: a normal Luau number).\r\n\r\nThis function does not check for precision loss. `f64` values lose precision past `2 ^ 53`.\r\n\r\n#### `to_dec_string`\r\n\r\n```luau\r\nint64.to_dec_string(u64: vector): string\r\n```\r\n\r\nReturns the provided value as a string of decimal digits.\r\n\r\nEquivalent to formatting normal numbers with `%u` or calling `tostring` on them.\r\n\r\n#### `to_pair`\r\n\r\n```luau\r\nint64.to_pair(u64: vector): (number, number)\r\n```\r\n\r\nConverts the provided `u64` into two 32-bit integers.\r\n\r\nThis returns the most significant portion of the number first.\r\n\r\n#### `to_quartet`\r\n\r\n```luau\r\nint64.to_quartet(u64: vector): (number, number, number, number)\r\n```\r\n\r\nConverts the provided `u64` into four 16-bit integers.\r\n\r\nThis returns the most significant portion of the number first.\r\n\r\n#### `to_buffer`\r\n\r\n```luau\r\nint64.to_buffer(u64: vector): buffer\r\n```\r\n\r\nConverts the provided `u64` to a buffer.\r\n\r\nThe integer is written as a little-endian value.\r\n\r\n#### `write_to_buffer`\r\n\r\n```luau\r\nint64.write_to_buffer(b: buffer, u64: vector, offset: number)\r\n```\r\n\r\nWrites the provided `u64` to the provided buffer. The value is written to the buffer at the provided offset.\r\n\r\nThe integer is written as a little-endian value.\r\n\r\n#### `to_byte_string`\r\n\r\n```luau\r\nint64.to_byte_string(u64: vector): string\r\n```\r\n\r\nConverts the provided `u64` to string of binary data.\r\n\r\nThe integer is written as if it were little-endian.\r\n\r\n#### `to_hex_string`\r\n\r\n```luau\r\nint64.to_hex_string(u64: vector): string\r\n```\r\n\r\nConverts the provided `u64` to a string of 16 hexadecimal digits.\r\n\r\nThe returned string will always be 16 bytes and the number is formatted as if it were big-endian. It also always uses lowercase letters.\r\n\r\n#### `to_bin_string`\r\n\r\n```luau\r\nint64.to_bin_string(u64: vector): string\r\n```\r\n\r\nConverts the provided `u64` to a string of 64 binary digits.\r\n\r\nThe returned string will always be 64 bytes and the number is formatted as if it were big-endian.\r\n\r\n### Constants\r\n\r\n#### `ZERO`\r\n\r\nA constant representing the 64-bit representation of `0`.\r\n\r\n#### `ONE`\r\n\r\nA constant representating the 64-bit representation of `1`.\r\n\r\n#### `TWO`\r\n\r\nA constant representating the 64-bit representation of `2`.\r\n\r\n#### `MAX`\r\n\r\nA constant representing the maximum possible 64-bit value (`18446744073709551615`, or `2 ^ 64 - 1`).\r\n\r\n#### `MAX_U32`\r\n\r\nA constant representing the maximum possible 32-bit value (`4294967295`, or `2 ^ 32 - 1`).\r\n\r\n#### `MAX_F64`\r\n\r\nA constant representing the maximum integer that is exactly representable by a normal Luau number (`9007199254740992` or `2 ^ 53`).\r\n\r\n#### `MAX_F32`\r\n\r\nA constant representing the maximum integer that is exactly representable by a 32-bit floating point value (`16777216`, or `2 ^ 24`).\r\n\r\n### Logical\r\n\r\n#### `gt`\r\n\r\n```luau\r\nint64.gt(lhs: vector, rhs: vector): boolean\r\n```\r\n\r\nReturns whether `lhs` is greater than `rhs`.\r\n\r\n#### `gt_equal`\r\n\r\n```luau\r\nint64.gt_equal(lhs: vector, rhs: vector): boolean\r\n```\r\n\r\nReturns whether `lhs` is greater than or equal to `rhs`.\r\n\r\n#### `lt`\r\n\r\n```luau\r\nint64.lt(lhs: vector, rhs: vector): boolean\r\n```\r\n\r\nReturns whether `lhs` is less than `rhs`.\r\n\r\n#### `lt_equal`\r\n\r\n```luau\r\nint64.lt_equal(lhs: vector, rhs: vector): boolean\r\n```\r\n\r\nReturns whether `lhs` is less than or equal to `rhs`.\r\n\r\n### Arithmetic\r\n\r\n#### `add`\r\n\r\n```luau\r\nint64.add(augend: vector, addend: vector): vector\r\n```\r\n\r\nCalculates the sum of the two provided values. Equivalent to `+` for normal integers.\r\n\r\nIf the sum is equal to or greater than `2 ^ 64`, the returned value will overflow rather than expanding beyond 64 bits.\r\n\r\n#### `sub`\r\n\r\n```luau\r\nint64.sub(minuend: vector, subtrahend: vector): vector\r\n```\r\n\r\nCalculates the difference of the two provided values. Equivalent to `-` for normal integers.\r\n\r\nIf the difference is less than `0`, the returned value will overflow rather than going negative.\r\n\r\n#### `mult`\r\n\r\n```luau\r\nint64.mult(multiplier: vector, multiplicand: vector): vector\r\n```\r\n\r\nCalculates the product of the two provided values. Equivalent to `*` for normal integers.\r\n\r\nIf the product is greater than or equal to `2 ^ 64`, the returned value will overflow rather than expanding beyond 64 bits.\r\n\r\n#### `div`\r\n\r\n```luau\r\nint64.div(dividend: vector, divisor: vector): (vector, vector)\r\n```\r\n\r\nCalculates the quotient of the two provided values and returns it, along with the remainder.\r\n\r\nEquivalent to `//` and `%` for normal integers.\r\nThis function will error if `divisor` is `0`.\r\n\r\n#### `pow`\r\n\r\n```luau\r\nint64.pow(base: vector, power: number): vector\r\n```\r\n\r\nCalculates the result of `base` raised to `power`. Equivalent to `^` for normal integers. `power` is interpreted as a 32-bit integer.\r\n\r\nIf the result is greater than or equal to `2 ^ 64`, the returned value will overflow rather than expanding beyond 64 bits.\r\n\r\nAdditionally, `0 ^ 0` is treated as being `1`.\r\n\r\n### Bitwise\r\n\r\n#### `band`\r\n\r\n```luau\r\nint64.band(lhs: vector, rhs: vector): vector\r\n```\r\n\r\nComputes the bitwise AND of the two provide values.\r\n\r\nThis does not accept a vararg like the `bit32` equivalent for performance reasons.\r\n\r\n#### `bor`\r\n\r\n```luau\r\nint64.bor(lhs: vector, rhs: vector): vector\r\n```\r\n\r\nComputes the bitwise OR of the two provide values.\r\n\r\nThis does not accept a vararg like the `bit32` equivalent for performance reasons.\r\n\r\n#### `bxor`\r\n\r\n```luau\r\nint64.bxor(lhs: vector, rhs: vector): vector\r\n```\r\n\r\nComputes the bitwise XOR of the two provide values.\r\n\r\nThis does not accept a vararg like the `bit32` equivalent for performance reasons.\r\n\r\n#### `bnot`\r\n\r\n```luau\r\nint64.bnot(u64: vector): vector\r\n```\r\n\r\nComputes the bitwise negation of the provided value.\r\n\r\n#### `lshift`\r\n\r\n```luau\r\nint64.lshift(u64: vector, n: number): vector\r\n```\r\n\r\nShifts the provided `u64` logically left by `n` bits.\r\n\r\nThis function will error if `n` is negative.\r\n\r\n#### `rshift`\r\n\r\n```luau\r\nint64.rshift(u64: vector, n: number): vector\r\n```\r\n\r\nShifts the provided `u64` logically right by `n` bits.\r\n\r\nThis function will error if `n` is negative.\r\n\r\n#### `arshift`\r\n\r\n```luau\r\nbit64.arshift(u64: vector, n: number): vector\r\n```\r\n\r\nShifts the provided `u64` arithmetically right by `n` bits. Since these numbers are unsigned, this effectively just copies the most significant bit into the empty space rather than filling them with zeros.\r\n\r\nThis function will error if `n` is negative.\r\n\r\n#### `lrotate`\r\n\r\n```luau\r\nint64.lrotate(u64: vector, n: number): vector\r\n```\r\n\r\nRotates the bits of the provided `u64` left by `n` bits.\r\n\r\nIf `n` is negative, this is equivalent to `rrotate`. Otherwise, if `n` is greater than 64-bits, it will wrap around.\r\n\r\n#### `rrotate`\r\n\r\n```luau\r\nint64.rrotate(u64: vector, n: number): vector\r\n```\r\n\r\nRotates the bits of the provided `u64` right by `n` bits.\r\n\r\nIf `n` is negative, this is equivalent to `lrotate`. Otherwise, if `n` is greater than 64-bits, it will wrap around.\r\n\r\n#### `countlz`\r\n\r\n```luau\r\nint64.countlz(u64: vector): number\r\n```\r\n\r\nReturns the number of consecutive zero bits in the provided `u64` starting from the left-most (most significant) bit.\r\n\r\n#### `countrz`\r\n\r\n```luau\r\nint64.countrz(u64: vector): number\r\n```\r\n\r\nReturns the number of consecutive zero bits in the provided `u64` starting from the right-most (least significant) bit.\r\n\r\n#### `btest`\r\n\r\n```luau\r\nint64.btest(lhs: vector, rhs: vector): boolean\r\n```\r\n\r\nReturns a boolean describing whether the bitwise AND of `lhs` and `rhs` are different than zero.\r\n\r\nThis does not accept a vararg like the `bit32` equivalent for performance reasons.\r\n\r\n#### `byteswap`\r\n\r\n```luau\r\nint64.byteswap(u64: vector): vector\r\n```\r\n\r\nReturns the provided `u64` with the order of bytes swapped.\r\n","readmeTruncated":false}