├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── bint.lua ├── docs ├── index.html └── ldoc.css ├── examples ├── bench.lua ├── e.lua ├── factorial.lua ├── fibonacci.lua ├── pi.lua ├── rsa.lua ├── secp256k1.lua └── simple.lua ├── rockspecs ├── bint-0.5.2-1.rockspec └── bint-dev-1.rockspec └── tests.lua /.gitignore: -------------------------------------------------------------------------------- 1 | *.out 2 | play.lua 3 | *.rock 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020-2024 Eduardo Bart (https://github.com/edubart) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ROCKSPEC=rockspecs/bint-0.*.rockspec 2 | LUA?=lua 3 | 4 | test: 5 | $(LUA) tests.lua 6 | $(LUA) examples/simple.lua 7 | $(LUA) examples/fibonacci.lua 8 | $(LUA) examples/factorial.lua 9 | $(LUA) examples/pi.lua 10 | $(LUA) examples/e.lua 11 | $(LUA) examples/rsa.lua 12 | $(LUA) examples/secp256k1.lua 13 | 14 | docs: 15 | ldoc -d docs -f markdown bint.lua 16 | 17 | coverage: 18 | rm -f *.out 19 | lua -lluacov tests.lua 20 | luacov 21 | 22 | clean: 23 | rm -f *.out 24 | 25 | install: 26 | luarocks make --local 27 | 28 | upload: 29 | luarocks upload --api-key=$(LUAROCKS_APIKEY) $(ROCKSPEC) 30 | 31 | .PHONY: test docs coverage clean 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lua Bint 2 | 3 | Small portable arbitrary-precision integer arithmetic library in pure Lua for 4 | computing with large integers. 5 | 6 | Different from most arbitrary-precision integer libraries in pure Lua out there this one 7 | uses an array of lua integers as underlying data-type in its implementation instead of 8 | using strings or large tables, this make it efficient for working with fixed width integers 9 | and to make bitwise operations. 10 | 11 | Bint stands for Big Integer. 12 | 13 | The library implementation was highly inspired by 14 | [tiny-bignum-c](https://github.com/kokke/tiny-bignum-c). 15 | 16 | This library was created to be used in the 17 | [Nelua programming language](https://github.com/edubart/nelua-lang) compiler. 18 | It is successfully used there to handle compile time operations on signed and unsigned integers. 19 | 20 | ## Design goals 21 | 22 | The main design goal of this library is to be small, correct, self contained and use few 23 | resources while retaining acceptable performance and feature completeness. 24 | 25 | The library is designed to follow recent Lua integer semantics, this means that 26 | integer overflow warps around, 27 | signed integers are implemented using two-complement arithmetic rules, 28 | integer division operations rounds towards minus infinity, 29 | any mixed operations with float numbers promotes the value to a float, 30 | and the usual division/power operation always promotes to floats. 31 | 32 | The library is designed to be possible to work with only unsigned integer arithmetic 33 | when using the proper methods. 34 | 35 | All the lua arithmetic operators (+, -, *, //, /, %) and bitwise operators (&, |, ~, <<, >>) 36 | are implemented as metamethods. 37 | 38 | The integer size must be fixed in advance and the library is designed to be more efficient when 39 | working with integers of sizes between 64-4096 bits. If you need to work with really huge numbers 40 | without size restrictions then use another library. This choice has been made to have more efficiency 41 | in that specific size range. 42 | 43 | ## Features 44 | 45 | * Small, simple and self contained. 46 | * Efficient (for a pure Lua integer library). 47 | * Works with fixed width integers. 48 | * Follows Lua 5.3+ integer arithmetic semantics by default. 49 | * All integer overflows wraps around. 50 | * Can work with large integer widths with reasonable speed (such as 1024bit integers). 51 | * Implements all lua arithmetic metamethods. 52 | * Provide methods to work with unsigned arithmetic only. 53 | * Supports signed integers by default using two-complement arithmetic rules on unsigned operations. 54 | * Allow to mix any operation with lua numbers, promoting to lua floats where needed. 55 | * Can perform bitwise operations. 56 | 57 | ## Documentation 58 | 59 | The full API reference and documentation can be viewed in the 60 | [documentation website](https://edubart.github.io/lua-bint/). 61 | 62 | ## Install 63 | 64 | You can use luarocks to install quickly: 65 | 66 | ```bash 67 | luarocks install bint 68 | ``` 69 | 70 | Or just copy the `bint.lua` file, the library is self contained in this single file with no dependencies. 71 | 72 | ## Examples 73 | 74 | ```lua 75 | local bint = require 'bint'(256) -- use 256 bits integers 76 | local x = bint(1) 77 | x = x << 128 78 | print(x) -- outputs: 340282366920938463463374607431768211456 79 | assert(tostring(x) == '340282366920938463463374607431768211456') 80 | ``` 81 | 82 | For more usage examples check the 83 | [examples directory](https://github.com/edubart/lua-bint/tree/master/examples). 84 | 85 | Some interesting examples there: 86 | 87 | * [factorial.lua](https://github.com/edubart/lua-bint/blob/master/examples/factorial.lua) - calculate factorial of 100 88 | * [fibonacci.lua](https://github.com/edubart/lua-bint/blob/master/examples/fibonacci.lua) - calculate the 1001th number of the Fibonacci sequence 89 | * [pi.lua](https://github.com/edubart/lua-bint/blob/master/examples/pi.lua) - calculate the first 100 digits of Pi 90 | * [e.lua](https://github.com/edubart/lua-bint/blob/master/examples/e.lua) - calculate the first 100 digits of Euler's number 91 | * [rsa.lua](https://github.com/edubart/lua-bint/blob/master/examples/rsa.lua) - simple RSA example for encrypting/decrypting messages 92 | * [secp256k1.lua](https://github.com/edubart/lua-bint/blob/master/examples/secp256k1.lua) - simple Secp256k1 elliptic curve example for encrypting/decrypting/signing messages 93 | 94 | ## Tests 95 | 96 | To check if everything is working as expected under your machine run `lua tests.lua` or `make test`. 97 | 98 | ## Limitations 99 | 100 | It is intended only to be used in Lua 5.3+. 101 | The library can theoretically be backported to Lua 5.1/LuaJIT but there is no plan at the moment. 102 | The integer size is limited in advance, this is a design choice. 103 | 104 | ## License 105 | 106 | MIT License 107 | -------------------------------------------------------------------------------- /bint.lua: -------------------------------------------------------------------------------- 1 | --[[-- 2 | lua-bint - v0.5.2 - 30/Oct/2024 3 | Eduardo Bart - edub4rt@gmail.com 4 | https://github.com/edubart/lua-bint 5 | 6 | Small portable arbitrary-precision integer arithmetic library in pure Lua for 7 | computing with large integers. 8 | 9 | Different from most arbitrary-precision integer libraries in pure Lua out there this one 10 | uses an array of lua integers as underlying data-type in its implementation instead of 11 | using strings or large tables, this make it efficient for working with fixed width integers 12 | and to make bitwise operations. 13 | 14 | ## Design goals 15 | 16 | The main design goal of this library is to be small, correct, self contained and use few 17 | resources while retaining acceptable performance and feature completeness. 18 | 19 | The library is designed to follow recent Lua integer semantics, this means that 20 | integer overflow warps around, 21 | signed integers are implemented using two-complement arithmetic rules, 22 | integer division operations rounds towards minus infinity, 23 | any mixed operations with float numbers promotes the value to a float, 24 | and the usual division/power operation always promotes to floats. 25 | 26 | The library is designed to be possible to work with only unsigned integer arithmetic 27 | when using the proper methods. 28 | 29 | All the lua arithmetic operators (+, -, *, //, /, %) and bitwise operators (&, |, ~, <<, >>) 30 | are implemented as metamethods. 31 | 32 | The integer size must be fixed in advance and the library is designed to be more efficient when 33 | working with integers of sizes between 64-4096 bits. If you need to work with really huge numbers 34 | without size restrictions then use another library. This choice has been made to have more efficiency 35 | in that specific size range. 36 | 37 | ## Usage 38 | 39 | First on you should require the bint file including how many bits the bint module will work with, 40 | by calling the returned function from the require, for example: 41 | 42 | ```lua 43 | local bint = require 'bint'(1024) 44 | ``` 45 | 46 | For more information about its arguments see @{newmodule}. 47 | Then when you need create a bint, you can use one of the following functions: 48 | 49 | * @{bint.fromuinteger} (convert from lua integers, but read as unsigned integer) 50 | * @{bint.frominteger} (convert from lua integers, preserving the sign) 51 | * @{bint.frombase} (convert from arbitrary bases, like hexadecimal) 52 | * @{bint.fromstring} (convert from arbitrary string, support binary/hexadecimal/decimal) 53 | * @{bint.trunc} (convert from lua numbers, truncating the fractional part) 54 | * @{bint.new} (convert from anything, asserts on invalid integers) 55 | * @{bint.tobint} (convert from anything, returns nil on invalid integers) 56 | * @{bint.parse} (convert from anything, returns a lua number as fallback) 57 | * @{bint.zero} 58 | * @{bint.one} 59 | * `bint` 60 | 61 | You can also call `bint` as it is an alias to `bint.new`. 62 | In doubt use @{bint.new} to create a new bint. 63 | 64 | Then you can use all the usual lua numeric operations on it, 65 | all the arithmetic metamethods are implemented. 66 | When you are done computing and need to get the result, 67 | get the output from one of the following functions: 68 | 69 | * @{bint.touinteger} (convert to a lua integer, wraps around as an unsigned integer) 70 | * @{bint.tointeger} (convert to a lua integer, wraps around, preserves the sign) 71 | * @{bint.tonumber} (convert to lua float, losing precision) 72 | * @{bint.tobase} (convert to a string in any base) 73 | * @{bint.__tostring} (convert to a string in base 10) 74 | 75 | To output a very large integer with no loss you probably want to use @{bint.tobase} 76 | or call `tostring` to get a string representation. 77 | 78 | ## Precautions 79 | 80 | All library functions can be mixed with lua numbers, 81 | this makes easy to mix operations between bints and lua numbers, 82 | however the user should take care in some situations: 83 | 84 | * Don't mix integers and float operations if you want to work with integers only. 85 | * Don't use the regular equal operator ('==') to compare values from this library, 86 | unless you know in advance that both values are of the same primitive type, 87 | otherwise it will always return false, use @{bint.eq} to be safe. 88 | * Don't pass fractional numbers to functions that an integer is expected 89 | * Don't mix operations between bint classes with different sizes as this is not supported, this 90 | will throw assertions. 91 | * Remember that casting back to lua integers or numbers precision can be lost. 92 | * For dividing while preserving integers use the @{bint.__idiv} (the '//' operator). 93 | * For doing power operation preserving integers use the @{bint.ipow} function. 94 | * Configure the proper integer size you intend to work with, otherwise large integers may wrap around. 95 | 96 | ## License 97 | 98 | MIT, see end of file. 99 | 100 | ]] 101 | 102 | -- Returns number of bits of the internal lua integer type. 103 | local function luainteger_bitsize() 104 | local n, i = -1, 0 105 | repeat 106 | n, i = n >> 16, i + 16 107 | until n==0 108 | return i 109 | end 110 | 111 | local math_type = math.type 112 | local math_floor = math.floor 113 | local math_abs = math.abs 114 | local math_ceil = math.ceil 115 | local math_modf = math.modf 116 | local math_mininteger = math.mininteger 117 | local math_maxinteger = math.maxinteger 118 | local math_max = math.max 119 | local math_min = math.min 120 | local string_format = string.format 121 | local table_insert = table.insert 122 | local table_concat = table.concat 123 | local table_unpack = table.unpack 124 | 125 | local memo = {} 126 | 127 | --- Create a new bint module representing integers of the desired bit size. 128 | -- This is the returned function when `require 'bint'` is called. 129 | -- @function newmodule 130 | -- @param bits Number of bits for the integer representation, must be multiple of wordbits and 131 | -- at least 64. 132 | -- @param[opt] wordbits Number of the bits for the internal word, 133 | -- defaults to half of Lua's integer size. 134 | local function newmodule(bits, wordbits) 135 | 136 | local intbits = luainteger_bitsize() 137 | bits = bits or 256 138 | wordbits = wordbits or (intbits // 2) 139 | 140 | -- Memoize bint modules 141 | local memoindex = bits * 64 + wordbits 142 | if memo[memoindex] then 143 | return memo[memoindex] 144 | end 145 | 146 | -- Validate 147 | assert(bits % wordbits == 0, 'bitsize is not multiple of word bitsize') 148 | assert(2*wordbits <= intbits, 'word bitsize must be half of the lua integer bitsize') 149 | assert(bits >= 64, 'bitsize must be >= 64') 150 | assert(wordbits >= 8, 'wordbits must be at least 8') 151 | assert(bits % 8 == 0, 'bitsize must be multiple of 8') 152 | 153 | -- Create bint module 154 | local bint = {} 155 | bint.__index = bint 156 | 157 | --- Number of bits representing a bint instance. 158 | bint.bits = bits 159 | 160 | -- Constants used internally 161 | local BINT_BITS = bits 162 | local BINT_BYTES = bits // 8 163 | local BINT_WORDBITS = wordbits 164 | local BINT_SIZE = BINT_BITS // BINT_WORDBITS 165 | local BINT_WORDMAX = (1 << BINT_WORDBITS) - 1 166 | local BINT_WORDMSB = (1 << (BINT_WORDBITS - 1)) 167 | local BINT_LEPACKFMT = '<'..('I'..(wordbits // 8)):rep(BINT_SIZE) 168 | local BINT_MATHMININTEGER, BINT_MATHMAXINTEGER 169 | local BINT_MININTEGER 170 | 171 | --- Create a new bint with 0 value. 172 | function bint.zero() 173 | local x = setmetatable({}, bint) 174 | for i=1,BINT_SIZE do 175 | x[i] = 0 176 | end 177 | return x 178 | end 179 | local bint_zero = bint.zero 180 | 181 | --- Create a new bint with 1 value. 182 | function bint.one() 183 | local x = setmetatable({}, bint) 184 | x[1] = 1 185 | for i=2,BINT_SIZE do 186 | x[i] = 0 187 | end 188 | return x 189 | end 190 | local bint_one = bint.one 191 | 192 | -- Convert a value to a lua integer without losing precision. 193 | local function tointeger(x) 194 | x = tonumber(x) 195 | local ty = math_type(x) 196 | if ty == 'float' then 197 | local floorx = math_floor(x) 198 | if floorx == x then 199 | x = floorx 200 | ty = math_type(x) 201 | end 202 | end 203 | if ty == 'integer' then 204 | return x 205 | end 206 | end 207 | 208 | --- Create a bint from an unsigned integer. 209 | -- Treats signed integers as an unsigned integer. 210 | -- @param x A value to initialize from convertible to a lua integer. 211 | -- @return A new bint or nil in case the input cannot be represented by an integer. 212 | -- @see bint.frominteger 213 | function bint.fromuinteger(x) 214 | x = tointeger(x) 215 | if x then 216 | if x == 1 then 217 | return bint_one() 218 | elseif x == 0 then 219 | return bint_zero() 220 | end 221 | local n = setmetatable({}, bint) 222 | for i=1,BINT_SIZE do 223 | n[i] = x & BINT_WORDMAX 224 | x = x >> BINT_WORDBITS 225 | end 226 | return n 227 | end 228 | end 229 | local bint_fromuinteger = bint.fromuinteger 230 | 231 | --- Create a bint from a signed integer. 232 | -- @param x A value to initialize from convertible to a lua integer. 233 | -- @return A new bint or nil in case the input cannot be represented by an integer. 234 | -- @see bint.fromuinteger 235 | function bint.frominteger(x) 236 | x = tointeger(x) 237 | if x then 238 | if x == 1 then 239 | return bint_one() 240 | elseif x == 0 then 241 | return bint_zero() 242 | end 243 | local neg = false 244 | if x < 0 then 245 | x = math_abs(x) 246 | neg = true 247 | end 248 | local n = setmetatable({}, bint) 249 | for i=1,BINT_SIZE do 250 | n[i] = x & BINT_WORDMAX 251 | x = x >> BINT_WORDBITS 252 | end 253 | if neg then 254 | n:_unm() 255 | end 256 | return n 257 | end 258 | end 259 | local bint_frominteger = bint.frominteger 260 | 261 | local basesteps = {} 262 | 263 | -- Compute the read step for frombase function 264 | local function getbasestep(base) 265 | local step = basesteps[base] 266 | if step then 267 | return step 268 | end 269 | step = 0 270 | local dmax = 1 271 | local limit = math_maxinteger // base 272 | repeat 273 | step = step + 1 274 | dmax = dmax * base 275 | until dmax >= limit 276 | basesteps[base] = step 277 | return step 278 | end 279 | 280 | -- Compute power with lua integers. 281 | local function ipow(y, x, n) 282 | if n == 1 then 283 | return y * x 284 | elseif n & 1 == 0 then --even 285 | return ipow(y, x * x, n // 2) 286 | end 287 | return ipow(x * y, x * x, (n-1) // 2) 288 | end 289 | 290 | --- Create a bint from a string of the desired base. 291 | -- @param s The string to be converted from, 292 | -- must have only alphanumeric and '+-' characters. 293 | -- @param[opt] base Base that the number is represented, defaults to 10. 294 | -- Must be at least 2 and at most 36. 295 | -- @return A new bint or nil in case the conversion failed. 296 | function bint.frombase(s, base) 297 | if type(s) ~= 'string' then 298 | return 299 | end 300 | base = base or 10 301 | if not (base >= 2 and base <= 36) then 302 | -- number base is too large 303 | return 304 | end 305 | local step = getbasestep(base) 306 | if #s < step then 307 | -- string is small, use tonumber (faster) 308 | return bint_frominteger(tonumber(s, base)) 309 | end 310 | local sign, int = s:lower():match('^([+-]?)(%w+)$') 311 | if not (sign and int) then 312 | -- invalid integer string representation 313 | return 314 | end 315 | local n = bint_zero() 316 | for i=1,#int,step do 317 | local part = int:sub(i,i+step-1) 318 | local d = tonumber(part, base) 319 | if not d then 320 | -- invalid integer string representation 321 | return 322 | end 323 | if i > 1 then 324 | n = n * ipow(1, base, #part) 325 | end 326 | if d ~= 0 then 327 | n:_add(d) 328 | end 329 | end 330 | if sign == '-' then 331 | n:_unm() 332 | end 333 | return n 334 | end 335 | local bint_frombase = bint.frombase 336 | 337 | --- Create a new bint from a string. 338 | -- The string can by a decimal number, binary number prefixed with '0b' or hexadecimal number prefixed with '0x'. 339 | -- @param s A string convertible to a bint. 340 | -- @return A new bint or nil in case the conversion failed. 341 | -- @see bint.frombase 342 | function bint.fromstring(s) 343 | if type(s) ~= 'string' then 344 | return 345 | end 346 | if s:find('^[+-]?[0-9]+$') then 347 | return bint_frombase(s, 10) 348 | elseif s:find('^[+-]?0[xX][0-9a-fA-F]+$') then 349 | return bint_frombase(s:gsub('0[xX]', '', 1), 16) 350 | elseif s:find('^[+-]?0[bB][01]+$') then 351 | return bint_frombase(s:gsub('0[bB]', '', 1), 2) 352 | end 353 | end 354 | local bint_fromstring = bint.fromstring 355 | 356 | --- Create a new bint from a buffer of little-endian bytes. 357 | -- @param buffer Buffer of bytes, extra bytes are trimmed from the right, missing bytes are padded to the right. 358 | -- @raise An assert is thrown in case buffer is not an string. 359 | -- @return A bint. 360 | function bint.fromle(buffer) 361 | assert(type(buffer) == 'string', 'buffer is not a string') 362 | if #buffer > BINT_BYTES then -- trim extra bytes from the right 363 | buffer = buffer:sub(1, BINT_BYTES) 364 | elseif #buffer < BINT_BYTES then -- add missing bytes to the right 365 | buffer = buffer..('\x00'):rep(BINT_BYTES - #buffer) 366 | end 367 | return setmetatable({BINT_LEPACKFMT:unpack(buffer)}, bint) 368 | end 369 | 370 | --- Create a new bint from a buffer of big-endian bytes. 371 | -- @param buffer Buffer of bytes, extra bytes are trimmed from the left, missing bytes are padded to the left. 372 | -- @raise An assert is thrown in case buffer is not an string. 373 | -- @return A bint. 374 | function bint.frombe(buffer) 375 | assert(type(buffer) == 'string', 'buffer is not a string') 376 | if #buffer > BINT_BYTES then -- trim extra bytes from the left 377 | buffer = buffer:sub(-BINT_BYTES, #buffer) 378 | elseif #buffer < BINT_BYTES then -- add missing bytes to the left 379 | buffer = ('\x00'):rep(BINT_BYTES - #buffer)..buffer 380 | end 381 | return setmetatable({BINT_LEPACKFMT:unpack(buffer:reverse())}, bint) 382 | end 383 | 384 | --- Create a new bint from a value. 385 | -- @param x A value convertible to a bint (string, number or another bint). 386 | -- @return A new bint, guaranteed to be a new reference in case needed. 387 | -- @raise An assert is thrown in case x is not convertible to a bint. 388 | -- @see bint.tobint 389 | -- @see bint.parse 390 | function bint.new(x) 391 | if getmetatable(x) ~= bint then 392 | local ty = type(x) 393 | if ty == 'number' then 394 | x = bint_frominteger(x) 395 | elseif ty == 'string' then 396 | x = bint_fromstring(x) 397 | end 398 | assert(x, 'value cannot be represented by a bint') 399 | return x 400 | end 401 | -- return a clone 402 | local n = setmetatable({}, bint) 403 | for i=1,BINT_SIZE do 404 | n[i] = x[i] 405 | end 406 | return n 407 | end 408 | local bint_new = bint.new 409 | 410 | --- Convert a value to a bint if possible. 411 | -- @param x A value to be converted (string, number or another bint). 412 | -- @param[opt] clone A boolean that tells if a new bint reference should be returned. 413 | -- Defaults to false. 414 | -- @return A bint or nil in case the conversion failed. 415 | -- @see bint.new 416 | -- @see bint.parse 417 | function bint.tobint(x, clone) 418 | if getmetatable(x) == bint then 419 | if not clone then 420 | return x 421 | end 422 | -- return a clone 423 | local n = setmetatable({}, bint) 424 | for i=1,BINT_SIZE do 425 | n[i] = x[i] 426 | end 427 | return n 428 | end 429 | local ty = type(x) 430 | if ty == 'number' then 431 | return bint_frominteger(x) 432 | elseif ty == 'string' then 433 | return bint_fromstring(x) 434 | end 435 | end 436 | local tobint = bint.tobint 437 | 438 | --- Convert a value to a bint if possible otherwise to a lua number. 439 | -- Useful to prepare values that you are unsure if it's going to be an integer or float. 440 | -- @param x A value to be converted (string, number or another bint). 441 | -- @param[opt] clone A boolean that tells if a new bint reference should be returned. 442 | -- Defaults to false. 443 | -- @return A bint or a lua number or nil in case the conversion failed. 444 | -- @see bint.new 445 | -- @see bint.tobint 446 | function bint.parse(x, clone) 447 | local i = tobint(x, clone) 448 | if i then 449 | return i 450 | end 451 | return tonumber(x) 452 | end 453 | local bint_parse = bint.parse 454 | 455 | --- Convert a bint to an unsigned integer. 456 | -- Note that large unsigned integers may be represented as negatives in lua integers. 457 | -- Note that lua cannot represent values larger than 64 bits, 458 | -- in that case integer values wrap around. 459 | -- @param x A bint or a number to be converted into an unsigned integer. 460 | -- @return An integer or nil in case the input cannot be represented by an integer. 461 | -- @see bint.tointeger 462 | function bint.touinteger(x) 463 | if getmetatable(x) == bint then 464 | local n = 0 465 | for i=1,BINT_SIZE do 466 | n = n | (x[i] << (BINT_WORDBITS * (i - 1))) 467 | end 468 | return n 469 | end 470 | return tointeger(x) 471 | end 472 | 473 | --- Convert a bint to a signed integer. 474 | -- It works by taking absolute values then applying the sign bit in case needed. 475 | -- Note that lua cannot represent values larger than 64 bits, 476 | -- in that case integer values wrap around. 477 | -- @param x A bint or value to be converted into an unsigned integer. 478 | -- @return An integer or nil in case the input cannot be represented by an integer. 479 | -- @see bint.touinteger 480 | function bint.tointeger(x) 481 | if getmetatable(x) == bint then 482 | local n = 0 483 | local neg = x:isneg() 484 | if neg then 485 | x = -x 486 | end 487 | for i=1,BINT_SIZE do 488 | n = n | (x[i] << (BINT_WORDBITS * (i - 1))) 489 | end 490 | if neg then 491 | n = -n 492 | end 493 | return n 494 | end 495 | return tointeger(x) 496 | end 497 | local bint_tointeger = bint.tointeger 498 | 499 | local function bint_assert_tointeger(x) 500 | x = bint_tointeger(x) 501 | if not x then 502 | error('value has no integer representation') 503 | end 504 | return x 505 | end 506 | 507 | --- Convert a bint to a lua float in case integer would wrap around or lua integer otherwise. 508 | -- Different from @{bint.tointeger} the operation does not wrap around integers, 509 | -- but digits precision are lost in the process of converting to a float. 510 | -- @param x A bint or value to be converted into a lua number. 511 | -- @return A lua number or nil in case the input cannot be represented by a number. 512 | -- @see bint.tointeger 513 | function bint.tonumber(x) 514 | if getmetatable(x) == bint then 515 | if x <= BINT_MATHMAXINTEGER and x >= BINT_MATHMININTEGER then 516 | return x:tointeger() 517 | end 518 | return tonumber(tostring(x)) 519 | end 520 | return tonumber(x) 521 | end 522 | local bint_tonumber = bint.tonumber 523 | 524 | -- Compute base letters to use in bint.tobase 525 | local BASE_LETTERS = {} 526 | do 527 | for i=1,36 do 528 | BASE_LETTERS[i-1] = ('0123456789abcdefghijklmnopqrstuvwxyz'):sub(i,i) 529 | end 530 | end 531 | 532 | --- Convert a bint to a string in the desired base. 533 | -- @param x The bint to be converted from. 534 | -- @param[opt] base Base to be represented, defaults to 10. 535 | -- Must be at least 2 and at most 36. 536 | -- @param[opt] unsigned Whether to output as an unsigned integer. 537 | -- Defaults to false for base 10 and true for others. 538 | -- When unsigned is false the symbol '-' is prepended in negative values. 539 | -- @return A string representing the input. 540 | -- @raise An assert is thrown in case the base is invalid. 541 | function bint.tobase(x, base, unsigned) 542 | x = tobint(x) 543 | if not x then 544 | -- x is a fractional float or something else 545 | return 546 | end 547 | base = base or 10 548 | if not (base >= 2 and base <= 36) then 549 | -- number base is too large 550 | return 551 | end 552 | if unsigned == nil then 553 | unsigned = base ~= 10 554 | end 555 | local isxneg = x:isneg() 556 | if (base == 10 and not unsigned) or (base == 16 and unsigned and not isxneg) then 557 | if x <= BINT_MATHMAXINTEGER and x >= BINT_MATHMININTEGER then 558 | -- integer is small, use tostring or string.format (faster) 559 | local n = x:tointeger() 560 | if base == 10 then 561 | return tostring(n) 562 | elseif unsigned then 563 | return string_format('%x', n) 564 | end 565 | end 566 | end 567 | local ss = {} 568 | local neg = not unsigned and isxneg 569 | x = neg and x:abs() or bint_new(x) 570 | local xiszero = x:iszero() 571 | if xiszero then 572 | return '0' 573 | end 574 | -- calculate basepow 575 | local step = 0 576 | local basepow = 1 577 | local limit = (BINT_WORDMSB - 1) // base 578 | repeat 579 | step = step + 1 580 | basepow = basepow * base 581 | until basepow >= limit 582 | -- serialize base digits 583 | local size = BINT_SIZE 584 | local xd, carry, d 585 | repeat 586 | -- single word division 587 | carry = 0 588 | xiszero = true 589 | for i=size,1,-1 do 590 | carry = carry | x[i] 591 | d, xd = carry // basepow, carry % basepow 592 | if xiszero and d ~= 0 then 593 | size = i 594 | xiszero = false 595 | end 596 | x[i] = d 597 | carry = xd << BINT_WORDBITS 598 | end 599 | -- digit division 600 | for _=1,step do 601 | xd, d = xd // base, xd % base 602 | if xiszero and xd == 0 and d == 0 then 603 | -- stop on leading zeros 604 | break 605 | end 606 | table_insert(ss, 1, BASE_LETTERS[d]) 607 | end 608 | until xiszero 609 | if neg then 610 | table_insert(ss, 1, '-') 611 | end 612 | return table_concat(ss) 613 | end 614 | 615 | local function bint_assert_convert(x) 616 | return assert(tobint(x), 'value has not integer representation') 617 | end 618 | 619 | --- Convert a bint to a buffer of little-endian bytes. 620 | -- @param x A bint or lua integer. 621 | -- @param[opt] trim If true, zero bytes on the right are trimmed. 622 | -- @return A buffer of bytes representing the input. 623 | -- @raise Asserts in case input is not convertible to an integer. 624 | function bint.tole(x, trim) 625 | x = bint_assert_convert(x) 626 | local s = BINT_LEPACKFMT:pack(table_unpack(x)) 627 | if trim then 628 | s = s:gsub('\x00+$', '') 629 | if s == '' then 630 | s = '\x00' 631 | end 632 | end 633 | return s 634 | end 635 | 636 | --- Convert a bint to a buffer of big-endian bytes. 637 | -- @param x A bint or lua integer. 638 | -- @param[opt] trim If true, zero bytes on the left are trimmed. 639 | -- @return A buffer of bytes representing the input. 640 | -- @raise Asserts in case input is not convertible to an integer. 641 | function bint.tobe(x, trim) 642 | x = bint_assert_convert(x) 643 | local s = BINT_LEPACKFMT:pack(table_unpack(x)):reverse() 644 | if trim then 645 | s = s:gsub('^\x00+', '') 646 | if s == '' then 647 | s = '\x00' 648 | end 649 | end 650 | return s 651 | end 652 | 653 | --- Check if a number is 0 considering bints. 654 | -- @param x A bint or a lua number. 655 | function bint.iszero(x) 656 | if getmetatable(x) == bint then 657 | for i=1,BINT_SIZE do 658 | if x[i] ~= 0 then 659 | return false 660 | end 661 | end 662 | return true 663 | end 664 | return x == 0 665 | end 666 | 667 | --- Check if a number is 1 considering bints. 668 | -- @param x A bint or a lua number. 669 | function bint.isone(x) 670 | if getmetatable(x) == bint then 671 | if x[1] ~= 1 then 672 | return false 673 | end 674 | for i=2,BINT_SIZE do 675 | if x[i] ~= 0 then 676 | return false 677 | end 678 | end 679 | return true 680 | end 681 | return x == 1 682 | end 683 | 684 | --- Check if a number is -1 considering bints. 685 | -- @param x A bint or a lua number. 686 | function bint.isminusone(x) 687 | if getmetatable(x) == bint then 688 | for i=1,BINT_SIZE do 689 | if x[i] ~= BINT_WORDMAX then 690 | return false 691 | end 692 | end 693 | return true 694 | end 695 | return x == -1 696 | end 697 | local bint_isminusone = bint.isminusone 698 | 699 | --- Check if the input is a bint. 700 | -- @param x Any lua value. 701 | function bint.isbint(x) 702 | return getmetatable(x) == bint 703 | end 704 | 705 | --- Check if the input is a lua integer or a bint. 706 | -- @param x Any lua value. 707 | function bint.isintegral(x) 708 | return getmetatable(x) == bint or math_type(x) == 'integer' 709 | end 710 | 711 | --- Check if the input is a bint or a lua number. 712 | -- @param x Any lua value. 713 | function bint.isnumeric(x) 714 | return getmetatable(x) == bint or type(x) == 'number' 715 | end 716 | 717 | --- Get the number type of the input (bint, integer or float). 718 | -- @param x Any lua value. 719 | -- @return Returns "bint" for bints, "integer" for lua integers, 720 | -- "float" from lua floats or nil otherwise. 721 | function bint.type(x) 722 | if getmetatable(x) == bint then 723 | return 'bint' 724 | end 725 | return math_type(x) 726 | end 727 | 728 | --- Check if a number is negative considering bints. 729 | -- Zero is guaranteed to never be negative for bints. 730 | -- @param x A bint or a lua number. 731 | function bint.isneg(x) 732 | if getmetatable(x) == bint then 733 | return x[BINT_SIZE] & BINT_WORDMSB ~= 0 734 | end 735 | return x < 0 736 | end 737 | local bint_isneg = bint.isneg 738 | 739 | --- Check if a number is positive considering bints. 740 | -- @param x A bint or a lua number. 741 | function bint.ispos(x) 742 | if getmetatable(x) == bint then 743 | return not x:isneg() and not x:iszero() 744 | end 745 | return x > 0 746 | end 747 | 748 | --- Check if a number is even considering bints. 749 | -- @param x A bint or a lua number. 750 | function bint.iseven(x) 751 | if getmetatable(x) == bint then 752 | return x[1] & 1 == 0 753 | end 754 | return math_abs(x) % 2 == 0 755 | end 756 | 757 | --- Check if a number is odd considering bints. 758 | -- @param x A bint or a lua number. 759 | function bint.isodd(x) 760 | if getmetatable(x) == bint then 761 | return x[1] & 1 == 1 762 | end 763 | return math_abs(x) % 2 == 1 764 | end 765 | 766 | --- Create a new bint with the maximum possible integer value. 767 | function bint.maxinteger() 768 | local x = setmetatable({}, bint) 769 | for i=1,BINT_SIZE-1 do 770 | x[i] = BINT_WORDMAX 771 | end 772 | x[BINT_SIZE] = BINT_WORDMAX ~ BINT_WORDMSB 773 | return x 774 | end 775 | 776 | --- Create a new bint with the minimum possible integer value. 777 | function bint.mininteger() 778 | local x = setmetatable({}, bint) 779 | for i=1,BINT_SIZE-1 do 780 | x[i] = 0 781 | end 782 | x[BINT_SIZE] = BINT_WORDMSB 783 | return x 784 | end 785 | 786 | --- Bitwise left shift a bint in one bit (in-place). 787 | function bint:_shlone() 788 | local wordbitsm1 = BINT_WORDBITS - 1 789 | for i=BINT_SIZE,2,-1 do 790 | self[i] = ((self[i] << 1) | (self[i-1] >> wordbitsm1)) & BINT_WORDMAX 791 | end 792 | self[1] = (self[1] << 1) & BINT_WORDMAX 793 | return self 794 | end 795 | 796 | --- Bitwise right shift a bint in one bit (in-place). 797 | function bint:_shrone() 798 | local wordbitsm1 = BINT_WORDBITS - 1 799 | for i=1,BINT_SIZE-1 do 800 | self[i] = ((self[i] >> 1) | (self[i+1] << wordbitsm1)) & BINT_WORDMAX 801 | end 802 | self[BINT_SIZE] = self[BINT_SIZE] >> 1 803 | return self 804 | end 805 | 806 | -- Bitwise left shift words of a bint (in-place). Used only internally. 807 | function bint:_shlwords(n) 808 | for i=BINT_SIZE,n+1,-1 do 809 | self[i] = self[i - n] 810 | end 811 | for i=1,n do 812 | self[i] = 0 813 | end 814 | return self 815 | end 816 | 817 | -- Bitwise right shift words of a bint (in-place). Used only internally. 818 | function bint:_shrwords(n) 819 | if n < BINT_SIZE then 820 | for i=1,BINT_SIZE-n do 821 | self[i] = self[i + n] 822 | end 823 | for i=BINT_SIZE-n+1,BINT_SIZE do 824 | self[i] = 0 825 | end 826 | else 827 | for i=1,BINT_SIZE do 828 | self[i] = 0 829 | end 830 | end 831 | return self 832 | end 833 | 834 | --- Increment a bint by one (in-place). 835 | function bint:_inc() 836 | for i=1,BINT_SIZE do 837 | local tmp = self[i] 838 | local v = (tmp + 1) & BINT_WORDMAX 839 | self[i] = v 840 | if v > tmp then 841 | break 842 | end 843 | end 844 | return self 845 | end 846 | 847 | --- Increment a number by one considering bints. 848 | -- @param x A bint or a lua number to increment. 849 | function bint.inc(x) 850 | local ix = tobint(x, true) 851 | if ix then 852 | return ix:_inc() 853 | end 854 | return x + 1 855 | end 856 | 857 | --- Decrement a bint by one (in-place). 858 | function bint:_dec() 859 | for i=1,BINT_SIZE do 860 | local tmp = self[i] 861 | local v = (tmp - 1) & BINT_WORDMAX 862 | self[i] = v 863 | if v <= tmp then 864 | break 865 | end 866 | end 867 | return self 868 | end 869 | 870 | --- Decrement a number by one considering bints. 871 | -- @param x A bint or a lua number to decrement. 872 | function bint.dec(x) 873 | local ix = tobint(x, true) 874 | if ix then 875 | return ix:_dec() 876 | end 877 | return x - 1 878 | end 879 | 880 | --- Assign a bint to a new value (in-place). 881 | -- @param y A value to be copied from. 882 | -- @raise Asserts in case inputs are not convertible to integers. 883 | function bint:_assign(y) 884 | y = bint_assert_convert(y) 885 | for i=1,BINT_SIZE do 886 | self[i] = y[i] 887 | end 888 | return self 889 | end 890 | 891 | --- Take absolute of a bint (in-place). 892 | function bint:_abs() 893 | if self:isneg() then 894 | self:_unm() 895 | end 896 | return self 897 | end 898 | 899 | --- Take absolute of a number considering bints. 900 | -- @param x A bint or a lua number to take the absolute. 901 | function bint.abs(x) 902 | local ix = tobint(x, true) 903 | if ix then 904 | return ix:_abs() 905 | end 906 | return math_abs(x) 907 | end 908 | local bint_abs = bint.abs 909 | 910 | --- Take the floor of a number considering bints. 911 | -- @param x A bint or a lua number to perform the floor operation. 912 | function bint.floor(x) 913 | if getmetatable(x) == bint then 914 | return bint_new(x) 915 | end 916 | return bint_new(math_floor(tonumber(x))) 917 | end 918 | 919 | --- Take ceil of a number considering bints. 920 | -- @param x A bint or a lua number to perform the ceil operation. 921 | function bint.ceil(x) 922 | if getmetatable(x) == bint then 923 | return bint_new(x) 924 | end 925 | return bint_new(math_ceil(tonumber(x))) 926 | end 927 | 928 | --- Wrap around bits of an integer (discarding left bits) considering bints. 929 | -- @param x A bint or a lua integer. 930 | -- @param y Number of right bits to preserve. 931 | function bint.bwrap(x, y) 932 | x = bint_assert_convert(x) 933 | if y <= 0 then 934 | return bint_zero() 935 | elseif y < BINT_BITS then 936 | return x & (bint_one() << y):_dec() 937 | end 938 | return bint_new(x) 939 | end 940 | 941 | --- Rotate left integer x by y bits considering bints. 942 | -- @param x A bint or a lua integer. 943 | -- @param y Number of bits to rotate. 944 | function bint.brol(x, y) 945 | x, y = bint_assert_convert(x), bint_assert_tointeger(y) 946 | if y > 0 then 947 | return (x << y) | (x >> (BINT_BITS - y)) 948 | elseif y < 0 then 949 | if y ~= math_mininteger then 950 | return x:bror(-y) 951 | else 952 | x:bror(-(y+1)) 953 | x:bror(1) 954 | end 955 | end 956 | return x 957 | end 958 | 959 | --- Rotate right integer x by y bits considering bints. 960 | -- @param x A bint or a lua integer. 961 | -- @param y Number of bits to rotate. 962 | function bint.bror(x, y) 963 | x, y = bint_assert_convert(x), bint_assert_tointeger(y) 964 | if y > 0 then 965 | return (x >> y) | (x << (BINT_BITS - y)) 966 | elseif y < 0 then 967 | if y ~= math_mininteger then 968 | return x:brol(-y) 969 | else 970 | x:brol(-(y+1)) 971 | x:brol(1) 972 | end 973 | end 974 | return x 975 | end 976 | 977 | --- Truncate a number to a bint. 978 | -- Floats numbers are truncated, that is, the fractional port is discarded. 979 | -- @param x A number to truncate. 980 | -- @return A new bint or nil in case the input does not fit in a bint or is not a number. 981 | function bint.trunc(x) 982 | if getmetatable(x) ~= bint then 983 | x = tonumber(x) 984 | if x then 985 | local ty = math_type(x) 986 | if ty == 'float' then 987 | -- truncate to integer 988 | x = math_modf(x) 989 | end 990 | return bint_frominteger(x) 991 | end 992 | return 993 | end 994 | return bint_new(x) 995 | end 996 | 997 | --- Take maximum between two numbers considering bints. 998 | -- @param x A bint or lua number to compare. 999 | -- @param y A bint or lua number to compare. 1000 | -- @return A bint or a lua number. Guarantees to return a new bint for integer values. 1001 | function bint.max(x, y) 1002 | local ix, iy = tobint(x), tobint(y) 1003 | if ix and iy then 1004 | return bint_new(ix > iy and ix or iy) 1005 | end 1006 | return bint_parse(math_max(x, y)) 1007 | end 1008 | 1009 | --- Take minimum between two numbers considering bints. 1010 | -- @param x A bint or lua number to compare. 1011 | -- @param y A bint or lua number to compare. 1012 | -- @return A bint or a lua number. Guarantees to return a new bint for integer values. 1013 | function bint.min(x, y) 1014 | local ix, iy = tobint(x), tobint(y) 1015 | if ix and iy then 1016 | return bint_new(ix < iy and ix or iy) 1017 | end 1018 | return bint_parse(math_min(x, y)) 1019 | end 1020 | 1021 | --- Add an integer to a bint (in-place). 1022 | -- @param y An integer to be added. 1023 | -- @raise Asserts in case inputs are not convertible to integers. 1024 | function bint:_add(y) 1025 | y = bint_assert_convert(y) 1026 | local carry = 0 1027 | for i=1,BINT_SIZE do 1028 | local tmp = self[i] + y[i] + carry 1029 | carry = tmp >> BINT_WORDBITS 1030 | self[i] = tmp & BINT_WORDMAX 1031 | end 1032 | return self 1033 | end 1034 | 1035 | --- Add two numbers considering bints. 1036 | -- @param x A bint or a lua number to be added. 1037 | -- @param y A bint or a lua number to be added. 1038 | function bint.__add(x, y) 1039 | local ix, iy = tobint(x), tobint(y) 1040 | if ix and iy then 1041 | local z = setmetatable({}, bint) 1042 | local carry = 0 1043 | for i=1,BINT_SIZE do 1044 | local tmp = ix[i] + iy[i] + carry 1045 | carry = tmp >> BINT_WORDBITS 1046 | z[i] = tmp & BINT_WORDMAX 1047 | end 1048 | return z 1049 | end 1050 | return bint_tonumber(x) + bint_tonumber(y) 1051 | end 1052 | 1053 | --- Subtract an integer from a bint (in-place). 1054 | -- @param y An integer to subtract. 1055 | -- @raise Asserts in case inputs are not convertible to integers. 1056 | function bint:_sub(y) 1057 | y = bint_assert_convert(y) 1058 | local borrow = 0 1059 | local wordmaxp1 = BINT_WORDMAX + 1 1060 | for i=1,BINT_SIZE do 1061 | local res = self[i] + wordmaxp1 - y[i] - borrow 1062 | self[i] = res & BINT_WORDMAX 1063 | borrow = (res >> BINT_WORDBITS) ~ 1 1064 | end 1065 | return self 1066 | end 1067 | 1068 | --- Subtract two numbers considering bints. 1069 | -- @param x A bint or a lua number to be subtracted from. 1070 | -- @param y A bint or a lua number to subtract. 1071 | function bint.__sub(x, y) 1072 | local ix, iy = tobint(x), tobint(y) 1073 | if ix and iy then 1074 | local z = setmetatable({}, bint) 1075 | local borrow = 0 1076 | local wordmaxp1 = BINT_WORDMAX + 1 1077 | for i=1,BINT_SIZE do 1078 | local res = ix[i] + wordmaxp1 - iy[i] - borrow 1079 | z[i] = res & BINT_WORDMAX 1080 | borrow = (res >> BINT_WORDBITS) ~ 1 1081 | end 1082 | return z 1083 | end 1084 | return bint_tonumber(x) - bint_tonumber(y) 1085 | end 1086 | 1087 | --- Multiply two numbers considering bints. 1088 | -- @param x A bint or a lua number to multiply. 1089 | -- @param y A bint or a lua number to multiply. 1090 | function bint.__mul(x, y) 1091 | local ix, iy = tobint(x), tobint(y) 1092 | if ix and iy then 1093 | local z = bint_zero() 1094 | local sizep1 = BINT_SIZE+1 1095 | local s = sizep1 1096 | local e = 0 1097 | for i=1,BINT_SIZE do 1098 | if ix[i] ~= 0 or iy[i] ~= 0 then 1099 | e = math_max(e, i) 1100 | s = math_min(s, i) 1101 | end 1102 | end 1103 | for i=s,e do 1104 | for j=s,math_min(sizep1-i,e) do 1105 | local a = ix[i] * iy[j] 1106 | if a ~= 0 then 1107 | local carry = 0 1108 | for k=i+j-1,BINT_SIZE do 1109 | local tmp = z[k] + (a & BINT_WORDMAX) + carry 1110 | carry = tmp >> BINT_WORDBITS 1111 | z[k] = tmp & BINT_WORDMAX 1112 | a = a >> BINT_WORDBITS 1113 | end 1114 | end 1115 | end 1116 | end 1117 | return z 1118 | end 1119 | return bint_tonumber(x) * bint_tonumber(y) 1120 | end 1121 | 1122 | --- Check if bints are equal. 1123 | -- @param x A bint to compare. 1124 | -- @param y A bint to compare. 1125 | function bint.__eq(x, y) 1126 | for i=1,BINT_SIZE do 1127 | if x[i] ~= y[i] then 1128 | return false 1129 | end 1130 | end 1131 | return true 1132 | end 1133 | 1134 | --- Check if numbers are equal considering bints. 1135 | -- @param x A bint or lua number to compare. 1136 | -- @param y A bint or lua number to compare. 1137 | function bint.eq(x, y) 1138 | local ix, iy = tobint(x), tobint(y) 1139 | if ix and iy then 1140 | return ix == iy 1141 | end 1142 | return x == y 1143 | end 1144 | local bint_eq = bint.eq 1145 | 1146 | local function findleftbit(x) 1147 | for i=BINT_SIZE,1,-1 do 1148 | local v = x[i] 1149 | if v ~= 0 then 1150 | local j = 0 1151 | repeat 1152 | v = v >> 1 1153 | j = j + 1 1154 | until v == 0 1155 | return (i-1)*BINT_WORDBITS + j - 1, i 1156 | end 1157 | end 1158 | end 1159 | 1160 | -- Single word division modulus 1161 | local function sudivmod(nume, deno) 1162 | local rema 1163 | local carry = 0 1164 | for i=BINT_SIZE,1,-1 do 1165 | carry = carry | nume[i] 1166 | nume[i] = carry // deno 1167 | rema = carry % deno 1168 | carry = rema << BINT_WORDBITS 1169 | end 1170 | return rema 1171 | end 1172 | 1173 | --- Perform unsigned division and modulo operation between two integers considering bints. 1174 | -- This is effectively the same of @{bint.udiv} and @{bint.umod}. 1175 | -- @param x The numerator, must be a bint or a lua integer. 1176 | -- @param y The denominator, must be a bint or a lua integer. 1177 | -- @return The quotient following the remainder, both bints. 1178 | -- @raise Asserts on attempt to divide by zero 1179 | -- or if inputs are not convertible to integers. 1180 | -- @see bint.udiv 1181 | -- @see bint.umod 1182 | function bint.udivmod(x, y) 1183 | local nume = bint_new(x) 1184 | local deno = bint_assert_convert(y) 1185 | -- compute if high bits of denominator are all zeros 1186 | local ishighzero = true 1187 | for i=2,BINT_SIZE do 1188 | if deno[i] ~= 0 then 1189 | ishighzero = false 1190 | break 1191 | end 1192 | end 1193 | if ishighzero then 1194 | -- try to divide by a single word (optimization) 1195 | local low = deno[1] 1196 | assert(low ~= 0, 'attempt to divide by zero') 1197 | if low == 1 then 1198 | -- denominator is one 1199 | return nume, bint_zero() 1200 | elseif low <= (BINT_WORDMSB - 1) then 1201 | -- can do single word division 1202 | local rema = sudivmod(nume, low) 1203 | return nume, bint_fromuinteger(rema) 1204 | end 1205 | end 1206 | if nume:ult(deno) then 1207 | -- denominator is greater than numerator 1208 | return bint_zero(), nume 1209 | end 1210 | -- align leftmost digits in numerator and denominator 1211 | local denolbit = findleftbit(deno) 1212 | local numelbit, numesize = findleftbit(nume) 1213 | local bit = numelbit - denolbit 1214 | deno = deno << bit 1215 | local wordmaxp1 = BINT_WORDMAX + 1 1216 | local wordbitsm1 = BINT_WORDBITS - 1 1217 | local denosize = numesize 1218 | local quot = bint_zero() 1219 | while bit >= 0 do 1220 | -- compute denominator <= numerator 1221 | local le = true 1222 | local size = math_max(numesize, denosize) 1223 | for i=size,1,-1 do 1224 | local a, b = deno[i], nume[i] 1225 | if a ~= b then 1226 | le = a < b 1227 | break 1228 | end 1229 | end 1230 | -- if the portion of the numerator above the denominator is greater or equal than to the denominator 1231 | if le then 1232 | -- subtract denominator from the portion of the numerator 1233 | local borrow = 0 1234 | for i=1,size do 1235 | local res = nume[i] + wordmaxp1 - deno[i] - borrow 1236 | nume[i] = res & BINT_WORDMAX 1237 | borrow = (res >> BINT_WORDBITS) ~ 1 1238 | end 1239 | -- concatenate 1 to the right bit of the quotient 1240 | local i = (bit // BINT_WORDBITS) + 1 1241 | quot[i] = quot[i] | (1 << (bit % BINT_WORDBITS)) 1242 | end 1243 | -- shift right the denominator in one bit 1244 | for i=1,denosize-1 do 1245 | deno[i] = ((deno[i] >> 1) | (deno[i+1] << wordbitsm1)) & BINT_WORDMAX 1246 | end 1247 | local lastdenoword = deno[denosize] >> 1 1248 | deno[denosize] = lastdenoword 1249 | -- recalculate denominator size (optimization) 1250 | if lastdenoword == 0 then 1251 | while deno[denosize] == 0 do 1252 | denosize = denosize - 1 1253 | end 1254 | if denosize == 0 then 1255 | break 1256 | end 1257 | end 1258 | -- decrement current set bit for the quotient 1259 | bit = bit - 1 1260 | end 1261 | -- the remaining numerator is the remainder 1262 | return quot, nume 1263 | end 1264 | local bint_udivmod = bint.udivmod 1265 | 1266 | --- Perform unsigned division between two integers considering bints. 1267 | -- @param x The numerator, must be a bint or a lua integer. 1268 | -- @param y The denominator, must be a bint or a lua integer. 1269 | -- @return The quotient, a bint. 1270 | -- @raise Asserts on attempt to divide by zero 1271 | -- or if inputs are not convertible to integers. 1272 | function bint.udiv(x, y) 1273 | return (bint_udivmod(x, y)) 1274 | end 1275 | 1276 | --- Perform unsigned integer modulo operation between two integers considering bints. 1277 | -- @param x The numerator, must be a bint or a lua integer. 1278 | -- @param y The denominator, must be a bint or a lua integer. 1279 | -- @return The remainder, a bint. 1280 | -- @raise Asserts on attempt to divide by zero 1281 | -- or if the inputs are not convertible to integers. 1282 | function bint.umod(x, y) 1283 | local _, rema = bint_udivmod(x, y) 1284 | return rema 1285 | end 1286 | local bint_umod = bint.umod 1287 | 1288 | --- Perform integer truncate division and modulo operation between two numbers considering bints. 1289 | -- This is effectively the same of @{bint.tdiv} and @{bint.tmod}. 1290 | -- @param x The numerator, a bint or lua number. 1291 | -- @param y The denominator, a bint or lua number. 1292 | -- @return The quotient following the remainder, both bint or lua number. 1293 | -- @raise Asserts on attempt to divide by zero or on division overflow. 1294 | -- @see bint.tdiv 1295 | -- @see bint.tmod 1296 | function bint.tdivmod(x, y) 1297 | local ax, ay = bint_abs(x), bint_abs(y) 1298 | local ix, iy = tobint(ax), tobint(ay) 1299 | local quot, rema 1300 | if ix and iy then 1301 | assert(not (bint_eq(x, BINT_MININTEGER) and bint_isminusone(y)), 'division overflow') 1302 | quot, rema = bint_udivmod(ix, iy) 1303 | else 1304 | quot, rema = ax // ay, ax % ay 1305 | end 1306 | local isxneg, isyneg = bint_isneg(x), bint_isneg(y) 1307 | if isxneg ~= isyneg then 1308 | quot = -quot 1309 | end 1310 | if isxneg then 1311 | rema = -rema 1312 | end 1313 | return quot, rema 1314 | end 1315 | local bint_tdivmod = bint.tdivmod 1316 | 1317 | --- Perform truncate division between two numbers considering bints. 1318 | -- Truncate division is a division that rounds the quotient towards zero. 1319 | -- @param x The numerator, a bint or lua number. 1320 | -- @param y The denominator, a bint or lua number. 1321 | -- @return The quotient, a bint or lua number. 1322 | -- @raise Asserts on attempt to divide by zero or on division overflow. 1323 | function bint.tdiv(x, y) 1324 | return (bint_tdivmod(x, y)) 1325 | end 1326 | 1327 | --- Perform integer truncate modulo operation between two numbers considering bints. 1328 | -- The operation is defined as the remainder of the truncate division 1329 | -- (division that rounds the quotient towards zero). 1330 | -- @param x The numerator, a bint or lua number. 1331 | -- @param y The denominator, a bint or lua number. 1332 | -- @return The remainder, a bint or lua number. 1333 | -- @raise Asserts on attempt to divide by zero or on division overflow. 1334 | function bint.tmod(x, y) 1335 | local _, rema = bint_tdivmod(x, y) 1336 | return rema 1337 | end 1338 | 1339 | --- Perform integer floor division and modulo operation between two numbers considering bints. 1340 | -- This is effectively the same of @{bint.__idiv} and @{bint.__mod}. 1341 | -- @param x The numerator, a bint or lua number. 1342 | -- @param y The denominator, a bint or lua number. 1343 | -- @return The quotient following the remainder, both bint or lua number. 1344 | -- @raise Asserts on attempt to divide by zero. 1345 | -- @see bint.__idiv 1346 | -- @see bint.__mod 1347 | function bint.idivmod(x, y) 1348 | local ix, iy = tobint(x), tobint(y) 1349 | if ix and iy then 1350 | local isnumeneg = ix[BINT_SIZE] & BINT_WORDMSB ~= 0 1351 | local isdenoneg = iy[BINT_SIZE] & BINT_WORDMSB ~= 0 1352 | if isnumeneg then 1353 | ix = -ix 1354 | end 1355 | if isdenoneg then 1356 | iy = -iy 1357 | end 1358 | local quot, rema = bint_udivmod(ix, iy) 1359 | if isnumeneg ~= isdenoneg then 1360 | quot:_unm() 1361 | -- round quotient towards minus infinity 1362 | if not rema:iszero() then 1363 | quot:_dec() 1364 | -- adjust the remainder 1365 | if isnumeneg and not isdenoneg then 1366 | rema:_unm():_add(y) 1367 | elseif isdenoneg and not isnumeneg then 1368 | rema:_add(y) 1369 | end 1370 | end 1371 | elseif isnumeneg then 1372 | -- adjust the remainder 1373 | rema:_unm() 1374 | end 1375 | return quot, rema 1376 | end 1377 | local nx, ny = bint_tonumber(x), bint_tonumber(y) 1378 | return nx // ny, nx % ny 1379 | end 1380 | local bint_idivmod = bint.idivmod 1381 | 1382 | --- Perform floor division between two numbers considering bints. 1383 | -- Floor division is a division that rounds the quotient towards minus infinity, 1384 | -- resulting in the floor of the division of its operands. 1385 | -- @param x The numerator, a bint or lua number. 1386 | -- @param y The denominator, a bint or lua number. 1387 | -- @return The quotient, a bint or lua number. 1388 | -- @raise Asserts on attempt to divide by zero. 1389 | function bint.__idiv(x, y) 1390 | local ix, iy = tobint(x), tobint(y) 1391 | if ix and iy then 1392 | local isnumeneg = ix[BINT_SIZE] & BINT_WORDMSB ~= 0 1393 | local isdenoneg = iy[BINT_SIZE] & BINT_WORDMSB ~= 0 1394 | if isnumeneg then 1395 | ix = -ix 1396 | end 1397 | if isdenoneg then 1398 | iy = -iy 1399 | end 1400 | local quot, rema = bint_udivmod(ix, iy) 1401 | if isnumeneg ~= isdenoneg then 1402 | quot:_unm() 1403 | -- round quotient towards minus infinity 1404 | if not rema:iszero() then 1405 | quot:_dec() 1406 | end 1407 | end 1408 | return quot, rema 1409 | end 1410 | return bint_tonumber(x) // bint_tonumber(y) 1411 | end 1412 | 1413 | --- Perform division between two numbers considering bints. 1414 | -- This always casts inputs to floats, for integer division only use @{bint.__idiv}. 1415 | -- @param x The numerator, a bint or lua number. 1416 | -- @param y The denominator, a bint or lua number. 1417 | -- @return The quotient, a lua number. 1418 | function bint.__div(x, y) 1419 | return bint_tonumber(x) / bint_tonumber(y) 1420 | end 1421 | 1422 | --- Perform integer floor modulo operation between two numbers considering bints. 1423 | -- The operation is defined as the remainder of the floor division 1424 | -- (division that rounds the quotient towards minus infinity). 1425 | -- @param x The numerator, a bint or lua number. 1426 | -- @param y The denominator, a bint or lua number. 1427 | -- @return The remainder, a bint or lua number. 1428 | -- @raise Asserts on attempt to divide by zero. 1429 | function bint.__mod(x, y) 1430 | local _, rema = bint_idivmod(x, y) 1431 | return rema 1432 | end 1433 | 1434 | --- Perform integer power between two integers considering bints. 1435 | -- If y is negative then pow is performed as an unsigned integer. 1436 | -- @param x The base, an integer. 1437 | -- @param y The exponent, an integer. 1438 | -- @return The result of the pow operation, a bint. 1439 | -- @raise Asserts in case inputs are not convertible to integers. 1440 | -- @see bint.__pow 1441 | -- @see bint.upowmod 1442 | function bint.ipow(x, y) 1443 | y = bint_assert_convert(y) 1444 | if y:iszero() then 1445 | return bint_one() 1446 | elseif y:isone() then 1447 | return bint_new(x) 1448 | end 1449 | -- compute exponentiation by squaring 1450 | x, y = bint_new(x), bint_new(y) 1451 | local z = bint_one() 1452 | repeat 1453 | if y:iseven() then 1454 | x = x * x 1455 | y:_shrone() 1456 | else 1457 | z = x * z 1458 | x = x * x 1459 | y:_dec():_shrone() 1460 | end 1461 | until y:isone() 1462 | return x * z 1463 | end 1464 | 1465 | --- Perform integer power between two unsigned integers over a modulus considering bints. 1466 | -- @param x The base, an integer. 1467 | -- @param y The exponent, an integer. 1468 | -- @param m The modulus, an integer. 1469 | -- @return The result of the pow operation, a bint. 1470 | -- @raise Asserts in case inputs are not convertible to integers. 1471 | -- @see bint.__pow 1472 | -- @see bint.ipow 1473 | function bint.upowmod(x, y, m) 1474 | m = bint_assert_convert(m) 1475 | if m:isone() then 1476 | return bint_zero() 1477 | end 1478 | x, y = bint_new(x), bint_new(y) 1479 | local z = bint_one() 1480 | x = bint_umod(x, m) 1481 | while not y:iszero() do 1482 | if y:isodd() then 1483 | z = bint_umod(z*x, m) 1484 | end 1485 | y:_shrone() 1486 | x = bint_umod(x*x, m) 1487 | end 1488 | return z 1489 | end 1490 | 1491 | --- Perform numeric power between two numbers considering bints. 1492 | -- This always casts inputs to floats, for integer power only use @{bint.ipow}. 1493 | -- @param x The base, a bint or lua number. 1494 | -- @param y The exponent, a bint or lua number. 1495 | -- @return The result of the pow operation, a lua number. 1496 | -- @see bint.ipow 1497 | function bint.__pow(x, y) 1498 | return bint_tonumber(x) ^ bint_tonumber(y) 1499 | end 1500 | 1501 | --- Bitwise left shift integers considering bints. 1502 | -- @param x An integer to perform the bitwise shift. 1503 | -- @param y An integer with the number of bits to shift. 1504 | -- @return The result of shift operation, a bint. 1505 | -- @raise Asserts in case inputs are not convertible to integers. 1506 | function bint.__shl(x, y) 1507 | x, y = bint_new(x), bint_assert_tointeger(y) 1508 | if y == math_mininteger or math_abs(y) >= BINT_BITS then 1509 | return bint_zero() 1510 | end 1511 | if y < 0 then 1512 | return x >> -y 1513 | end 1514 | local nvals = y // BINT_WORDBITS 1515 | if nvals ~= 0 then 1516 | x:_shlwords(nvals) 1517 | y = y - nvals * BINT_WORDBITS 1518 | end 1519 | if y ~= 0 then 1520 | local wordbitsmy = BINT_WORDBITS - y 1521 | for i=BINT_SIZE,2,-1 do 1522 | x[i] = ((x[i] << y) | (x[i-1] >> wordbitsmy)) & BINT_WORDMAX 1523 | end 1524 | x[1] = (x[1] << y) & BINT_WORDMAX 1525 | end 1526 | return x 1527 | end 1528 | 1529 | --- Bitwise right shift integers considering bints. 1530 | -- @param x An integer to perform the bitwise shift. 1531 | -- @param y An integer with the number of bits to shift. 1532 | -- @return The result of shift operation, a bint. 1533 | -- @raise Asserts in case inputs are not convertible to integers. 1534 | function bint.__shr(x, y) 1535 | x, y = bint_new(x), bint_assert_tointeger(y) 1536 | if y == math_mininteger or math_abs(y) >= BINT_BITS then 1537 | return bint_zero() 1538 | end 1539 | if y < 0 then 1540 | return x << -y 1541 | end 1542 | local nvals = y // BINT_WORDBITS 1543 | if nvals ~= 0 then 1544 | x:_shrwords(nvals) 1545 | y = y - nvals * BINT_WORDBITS 1546 | end 1547 | if y ~= 0 then 1548 | local wordbitsmy = BINT_WORDBITS - y 1549 | for i=1,BINT_SIZE-1 do 1550 | x[i] = ((x[i] >> y) | (x[i+1] << wordbitsmy)) & BINT_WORDMAX 1551 | end 1552 | x[BINT_SIZE] = x[BINT_SIZE] >> y 1553 | end 1554 | return x 1555 | end 1556 | 1557 | --- Bitwise AND bints (in-place). 1558 | -- @param y An integer to perform bitwise AND. 1559 | -- @raise Asserts in case inputs are not convertible to integers. 1560 | function bint:_band(y) 1561 | y = bint_assert_convert(y) 1562 | for i=1,BINT_SIZE do 1563 | self[i] = self[i] & y[i] 1564 | end 1565 | return self 1566 | end 1567 | 1568 | --- Bitwise AND two integers considering bints. 1569 | -- @param x An integer to perform bitwise AND. 1570 | -- @param y An integer to perform bitwise AND. 1571 | -- @raise Asserts in case inputs are not convertible to integers. 1572 | function bint.__band(x, y) 1573 | return bint_new(x):_band(y) 1574 | end 1575 | 1576 | --- Bitwise OR bints (in-place). 1577 | -- @param y An integer to perform bitwise OR. 1578 | -- @raise Asserts in case inputs are not convertible to integers. 1579 | function bint:_bor(y) 1580 | y = bint_assert_convert(y) 1581 | for i=1,BINT_SIZE do 1582 | self[i] = self[i] | y[i] 1583 | end 1584 | return self 1585 | end 1586 | 1587 | --- Bitwise OR two integers considering bints. 1588 | -- @param x An integer to perform bitwise OR. 1589 | -- @param y An integer to perform bitwise OR. 1590 | -- @raise Asserts in case inputs are not convertible to integers. 1591 | function bint.__bor(x, y) 1592 | return bint_new(x):_bor(y) 1593 | end 1594 | 1595 | --- Bitwise XOR bints (in-place). 1596 | -- @param y An integer to perform bitwise XOR. 1597 | -- @raise Asserts in case inputs are not convertible to integers. 1598 | function bint:_bxor(y) 1599 | y = bint_assert_convert(y) 1600 | for i=1,BINT_SIZE do 1601 | self[i] = self[i] ~ y[i] 1602 | end 1603 | return self 1604 | end 1605 | 1606 | --- Bitwise XOR two integers considering bints. 1607 | -- @param x An integer to perform bitwise XOR. 1608 | -- @param y An integer to perform bitwise XOR. 1609 | -- @raise Asserts in case inputs are not convertible to integers. 1610 | function bint.__bxor(x, y) 1611 | return bint_new(x):_bxor(y) 1612 | end 1613 | 1614 | --- Bitwise NOT a bint (in-place). 1615 | function bint:_bnot() 1616 | for i=1,BINT_SIZE do 1617 | self[i] = (~self[i]) & BINT_WORDMAX 1618 | end 1619 | return self 1620 | end 1621 | 1622 | --- Bitwise NOT a bint. 1623 | -- @param x An integer to perform bitwise NOT. 1624 | -- @raise Asserts in case inputs are not convertible to integers. 1625 | function bint.__bnot(x) 1626 | local y = setmetatable({}, bint) 1627 | for i=1,BINT_SIZE do 1628 | y[i] = (~x[i]) & BINT_WORDMAX 1629 | end 1630 | return y 1631 | end 1632 | 1633 | --- Negate a bint (in-place). This effectively applies two's complements. 1634 | function bint:_unm() 1635 | return self:_bnot():_inc() 1636 | end 1637 | 1638 | --- Negate a bint. This effectively applies two's complements. 1639 | -- @param x A bint to perform negation. 1640 | function bint.__unm(x) 1641 | return (~x):_inc() 1642 | end 1643 | 1644 | --- Compare if integer x is less than y considering bints (unsigned version). 1645 | -- @param x Left integer to compare. 1646 | -- @param y Right integer to compare. 1647 | -- @raise Asserts in case inputs are not convertible to integers. 1648 | -- @see bint.__lt 1649 | function bint.ult(x, y) 1650 | x, y = bint_assert_convert(x), bint_assert_convert(y) 1651 | for i=BINT_SIZE,1,-1 do 1652 | local a, b = x[i], y[i] 1653 | if a ~= b then 1654 | return a < b 1655 | end 1656 | end 1657 | return false 1658 | end 1659 | 1660 | --- Compare if bint x is less or equal than y considering bints (unsigned version). 1661 | -- @param x Left integer to compare. 1662 | -- @param y Right integer to compare. 1663 | -- @raise Asserts in case inputs are not convertible to integers. 1664 | -- @see bint.__le 1665 | function bint.ule(x, y) 1666 | x, y = bint_assert_convert(x), bint_assert_convert(y) 1667 | for i=BINT_SIZE,1,-1 do 1668 | local a, b = x[i], y[i] 1669 | if a ~= b then 1670 | return a < b 1671 | end 1672 | end 1673 | return true 1674 | end 1675 | 1676 | --- Compare if number x is less than y considering bints and signs. 1677 | -- @param x Left value to compare, a bint or lua number. 1678 | -- @param y Right value to compare, a bint or lua number. 1679 | -- @see bint.ult 1680 | function bint.__lt(x, y) 1681 | local ix, iy = tobint(x), tobint(y) 1682 | if ix and iy then 1683 | local xneg = ix[BINT_SIZE] & BINT_WORDMSB ~= 0 1684 | local yneg = iy[BINT_SIZE] & BINT_WORDMSB ~= 0 1685 | if xneg == yneg then 1686 | for i=BINT_SIZE,1,-1 do 1687 | local a, b = ix[i], iy[i] 1688 | if a ~= b then 1689 | return a < b 1690 | end 1691 | end 1692 | return false 1693 | end 1694 | return xneg and not yneg 1695 | end 1696 | return bint_tonumber(x) < bint_tonumber(y) 1697 | end 1698 | 1699 | --- Compare if number x is less or equal than y considering bints and signs. 1700 | -- @param x Left value to compare, a bint or lua number. 1701 | -- @param y Right value to compare, a bint or lua number. 1702 | -- @see bint.ule 1703 | function bint.__le(x, y) 1704 | local ix, iy = tobint(x), tobint(y) 1705 | if ix and iy then 1706 | local xneg = ix[BINT_SIZE] & BINT_WORDMSB ~= 0 1707 | local yneg = iy[BINT_SIZE] & BINT_WORDMSB ~= 0 1708 | if xneg == yneg then 1709 | for i=BINT_SIZE,1,-1 do 1710 | local a, b = ix[i], iy[i] 1711 | if a ~= b then 1712 | return a < b 1713 | end 1714 | end 1715 | return true 1716 | end 1717 | return xneg and not yneg 1718 | end 1719 | return bint_tonumber(x) <= bint_tonumber(y) 1720 | end 1721 | 1722 | --- Convert a bint to a string on base 10. 1723 | -- @see bint.tobase 1724 | function bint:__tostring() 1725 | return self:tobase(10) 1726 | end 1727 | 1728 | -- Allow creating bints by calling bint itself 1729 | setmetatable(bint, { 1730 | __call = function(_, x) 1731 | return bint_new(x) 1732 | end 1733 | }) 1734 | 1735 | BINT_MATHMININTEGER, BINT_MATHMAXINTEGER = bint_new(math.mininteger), bint_new(math.maxinteger) 1736 | BINT_MININTEGER = bint.mininteger() 1737 | memo[memoindex] = bint 1738 | 1739 | return bint 1740 | 1741 | end 1742 | 1743 | return newmodule 1744 | 1745 | --[[ 1746 | The MIT License (MIT) 1747 | 1748 | Copyright (c) 2020-2024 Eduardo Bart (https://github.com/edubart) 1749 | 1750 | Permission is hereby granted, free of charge, to any person obtaining a copy 1751 | of this software and associated documentation files (the "Software"), to deal 1752 | in the Software without restriction, including without limitation the rights 1753 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 1754 | copies of the Software, and to permit persons to whom the Software is 1755 | furnished to do so, subject to the following conditions: 1756 | 1757 | The above copyright notice and this permission notice shall be included in all 1758 | copies or substantial portions of the Software. 1759 | 1760 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1761 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1762 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1763 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1764 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 1765 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 1766 | SOFTWARE. 1767 | ]] 1768 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | Reference 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 |
16 |
17 |
18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 44 | 45 |
46 | 47 |

Module bint

48 |

lua-bint - v0.5.2 - 30/Oct/2024 49 | Eduardo Bart - edub4rt@gmail.com 50 | https://github.com/edubart/lua-bint

51 | 52 |

Small portable arbitrary-precision integer arithmetic library in pure Lua for 53 | computing with large integers.

54 |

Different from most arbitrary-precision integer libraries in pure Lua out there this one 55 | uses an array of lua integers as underlying data-type in its implementation instead of 56 | using strings or large tables, this make it efficient for working with fixed width integers 57 | and to make bitwise operations.

58 | 59 |

Design goals

60 | 61 |

The main design goal of this library is to be small, correct, self contained and use few 62 | resources while retaining acceptable performance and feature completeness.

63 | 64 |

The library is designed to follow recent Lua integer semantics, this means that 65 | integer overflow warps around, 66 | signed integers are implemented using two-complement arithmetic rules, 67 | integer division operations rounds towards minus infinity, 68 | any mixed operations with float numbers promotes the value to a float, 69 | and the usual division/power operation always promotes to floats.

70 | 71 |

The library is designed to be possible to work with only unsigned integer arithmetic 72 | when using the proper methods.

73 | 74 |

All the lua arithmetic operators (+, -, *, //, /, %) and bitwise operators (&, |, ~, <<, >>) 75 | are implemented as metamethods.

76 | 77 |

The integer size must be fixed in advance and the library is designed to be more efficient when 78 | working with integers of sizes between 64-4096 bits. If you need to work with really huge numbers 79 | without size restrictions then use another library. This choice has been made to have more efficiency 80 | in that specific size range.

81 | 82 |

Usage

83 | 84 |

First on you should require the bint file including how many bits the bint module will work with, 85 | by calling the returned function from the require, for example:

86 | 87 | 88 |
  89 | local bint = require 'bint'(1024)
  90 | 
91 | 92 | 93 |

For more information about its arguments see newmodule. 94 | Then when you need create a bint, you can use one of the following functions:

95 | 96 |
    97 |
  • bint.fromuinteger (convert from lua integers, but read as unsigned integer)
  • 98 |
  • bint.frominteger (convert from lua integers, preserving the sign)
  • 99 |
  • bint.frombase (convert from arbitrary bases, like hexadecimal)
  • 100 |
  • bint.fromstring (convert from arbitrary string, support binary/hexadecimal/decimal)
  • 101 |
  • bint.trunc (convert from lua numbers, truncating the fractional part)
  • 102 |
  • bint.new (convert from anything, asserts on invalid integers)
  • 103 |
  • bint.tobint (convert from anything, returns nil on invalid integers)
  • 104 |
  • bint.parse (convert from anything, returns a lua number as fallback)
  • 105 |
  • bint.zero
  • 106 |
  • bint.one
  • 107 |
  • bint
  • 108 |
109 | 110 |

You can also call bint as it is an alias to bint.new. 111 | In doubt use bint.new to create a new bint.

112 | 113 |

Then you can use all the usual lua numeric operations on it, 114 | all the arithmetic metamethods are implemented. 115 | When you are done computing and need to get the result, 116 | get the output from one of the following functions:

117 | 118 |
    119 |
  • bint.touinteger (convert to a lua integer, wraps around as an unsigned integer)
  • 120 |
  • bint.tointeger (convert to a lua integer, wraps around, preserves the sign)
  • 121 |
  • bint.tonumber (convert to lua float, losing precision)
  • 122 |
  • bint.tobase (convert to a string in any base)
  • 123 |
  • bint.__tostring (convert to a string in base 10)
  • 124 |
125 | 126 |

To output a very large integer with no loss you probably want to use bint.tobase 127 | or call tostring to get a string representation.

128 | 129 |

Precautions

130 | 131 |

All library functions can be mixed with lua numbers, 132 | this makes easy to mix operations between bints and lua numbers, 133 | however the user should take care in some situations:

134 | 135 |
    136 |
  • Don't mix integers and float operations if you want to work with integers only.
  • 137 |
  • Don't use the regular equal operator ('==') to compare values from this library, 138 | unless you know in advance that both values are of the same primitive type, 139 | otherwise it will always return false, use bint.eq to be safe.
  • 140 |
  • Don't pass fractional numbers to functions that an integer is expected
  • 141 |
  • Don't mix operations between bint classes with different sizes as this is not supported, this 142 | will throw assertions.
  • 143 |
  • Remember that casting back to lua integers or numbers precision can be lost.
  • 144 |
  • For dividing while preserving integers use the bint.__idiv (the '//' operator).
  • 145 |
  • For doing power operation preserving integers use the bint.ipow function.
  • 146 |
  • Configure the proper integer size you intend to work with, otherwise large integers may wrap around.
  • 147 |
148 | 149 |

License

150 | 151 |

MIT, see end of file.

152 | 153 | 154 |

Functions

155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 |
newmodule (bits[, wordbits])Create a new bint module representing integers of the desired bit size.
zero ()Create a new bint with 0 value.
one ()Create a new bint with 1 value.
fromuinteger (x)Create a bint from an unsigned integer.
frominteger (x)Create a bint from a signed integer.
frombase (s[, base])Create a bint from a string of the desired base.
fromstring (s)Create a new bint from a string.
fromle (buffer)Create a new bint from a buffer of little-endian bytes.
frombe (buffer)Create a new bint from a buffer of big-endian bytes.
new (x)Create a new bint from a value.
tobint (x[, clone])Convert a value to a bint if possible.
parse (x[, clone])Convert a value to a bint if possible otherwise to a lua number.
touinteger (x)Convert a bint to an unsigned integer.
tointeger (x)Convert a bint to a signed integer.
tonumber (x)Convert a bint to a lua float in case integer would wrap around or lua integer otherwise.
tobase (x[, base[, unsigned]])Convert a bint to a string in the desired base.
tole (x[, trim])Convert a bint to a buffer of little-endian bytes.
tobe (x[, trim])Convert a bint to a buffer of big-endian bytes.
iszero (x)Check if a number is 0 considering bints.
isone (x)Check if a number is 1 considering bints.
isminusone (x)Check if a number is -1 considering bints.
isbint (x)Check if the input is a bint.
isintegral (x)Check if the input is a lua integer or a bint.
isnumeric (x)Check if the input is a bint or a lua number.
type (x)Get the number type of the input (bint, integer or float).
isneg (x)Check if a number is negative considering bints.
ispos (x)Check if a number is positive considering bints.
iseven (x)Check if a number is even considering bints.
isodd (x)Check if a number is odd considering bints.
maxinteger ()Create a new bint with the maximum possible integer value.
mininteger ()Create a new bint with the minimum possible integer value.
_shlone ()Bitwise left shift a bint in one bit (in-place).
_shrone ()Bitwise right shift a bint in one bit (in-place).
_inc ()Increment a bint by one (in-place).
inc (x)Increment a number by one considering bints.
_dec ()Decrement a bint by one (in-place).
dec (x)Decrement a number by one considering bints.
_assign (y)Assign a bint to a new value (in-place).
_abs ()Take absolute of a bint (in-place).
abs (x)Take absolute of a number considering bints.
floor (x)Take the floor of a number considering bints.
ceil (x)Take ceil of a number considering bints.
bwrap (x, y)Wrap around bits of an integer (discarding left bits) considering bints.
brol (x, y)Rotate left integer x by y bits considering bints.
bror (x, y)Rotate right integer x by y bits considering bints.
trunc (x)Truncate a number to a bint.
max (x, y)Take maximum between two numbers considering bints.
min (x, y)Take minimum between two numbers considering bints.
_add (y)Add an integer to a bint (in-place).
__add (x, y)Add two numbers considering bints.
_sub (y)Subtract an integer from a bint (in-place).
__sub (x, y)Subtract two numbers considering bints.
__mul (x, y)Multiply two numbers considering bints.
__eq (x, y)Check if bints are equal.
eq (x, y)Check if numbers are equal considering bints.
udivmod (x, y)Perform unsigned division and modulo operation between two integers considering bints.
udiv (x, y)Perform unsigned division between two integers considering bints.
umod (x, y)Perform unsigned integer modulo operation between two integers considering bints.
tdivmod (x, y)Perform integer truncate division and modulo operation between two numbers considering bints.
tdiv (x, y)Perform truncate division between two numbers considering bints.
tmod (x, y)Perform integer truncate modulo operation between two numbers considering bints.
idivmod (x, y)Perform integer floor division and modulo operation between two numbers considering bints.
__idiv (x, y)Perform floor division between two numbers considering bints.
__div (x, y)Perform division between two numbers considering bints.
__mod (x, y)Perform integer floor modulo operation between two numbers considering bints.
ipow (x, y)Perform integer power between two integers considering bints.
upowmod (x, y, m)Perform integer power between two unsigned integers over a modulus considering bints.
__pow (x, y)Perform numeric power between two numbers considering bints.
__shl (x, y)Bitwise left shift integers considering bints.
__shr (x, y)Bitwise right shift integers considering bints.
_band (y)Bitwise AND bints (in-place).
__band (x, y)Bitwise AND two integers considering bints.
_bor (y)Bitwise OR bints (in-place).
__bor (x, y)Bitwise OR two integers considering bints.
_bxor (y)Bitwise XOR bints (in-place).
__bxor (x, y)Bitwise XOR two integers considering bints.
_bnot ()Bitwise NOT a bint (in-place).
__bnot (x)Bitwise NOT a bint.
_unm ()Negate a bint (in-place).
__unm (x)Negate a bint.
ult (x, y)Compare if integer x is less than y considering bints (unsigned version).
ule (x, y)Compare if bint x is less or equal than y considering bints (unsigned version).
__lt (x, y)Compare if number x is less than y considering bints and signs.
__le (x, y)Compare if number x is less or equal than y considering bints and signs.
__tostring ()Convert a bint to a string on base 10.
497 |

Fields

498 | 499 | 500 | 501 | 502 | 503 |
bitsNumber of bits representing a bint instance.
504 | 505 |
506 |
507 | 508 | 509 |

Functions

510 | 511 |
512 |
513 | 514 | newmodule (bits[, wordbits]) 515 |
516 |
517 | Create a new bint module representing integers of the desired bit size. 518 | This is the returned function when require 'bint' is called. 519 | 520 | 521 |

Parameters:

522 |
    523 |
  • bits 524 | Number of bits for the integer representation, must be multiple of wordbits and 525 | at least 64. 526 |
  • 527 |
  • wordbits 528 | Number of the bits for the internal word, 529 | defaults to half of Lua's integer size. 530 | (optional) 531 |
  • 532 |
533 | 534 | 535 | 536 | 537 | 538 |
539 |
540 | 541 | zero () 542 |
543 |
544 | Create a new bint with 0 value. 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 |
553 |
554 | 555 | one () 556 |
557 |
558 | Create a new bint with 1 value. 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 |
567 |
568 | 569 | fromuinteger (x) 570 |
571 |
572 | Create a bint from an unsigned integer. 573 | Treats signed integers as an unsigned integer. 574 | 575 | 576 |

Parameters:

577 |
    578 |
  • x 579 | A value to initialize from convertible to a lua integer. 580 |
  • 581 |
582 | 583 |

Returns:

584 |
    585 | 586 | A new bint or nil in case the input cannot be represented by an integer. 587 |
588 | 589 | 590 |

See also:

591 | 594 | 595 | 596 |
597 |
598 | 599 | frominteger (x) 600 |
601 |
602 | Create a bint from a signed integer. 603 | 604 | 605 |

Parameters:

606 |
    607 |
  • x 608 | A value to initialize from convertible to a lua integer. 609 |
  • 610 |
611 | 612 |

Returns:

613 |
    614 | 615 | A new bint or nil in case the input cannot be represented by an integer. 616 |
617 | 618 | 619 |

See also:

620 | 623 | 624 | 625 |
626 |
627 | 628 | frombase (s[, base]) 629 |
630 |
631 | Create a bint from a string of the desired base. 632 | 633 | 634 |

Parameters:

635 |
    636 |
  • s 637 | The string to be converted from, 638 | must have only alphanumeric and '+-' characters. 639 |
  • 640 |
  • base 641 | Base that the number is represented, defaults to 10. 642 | Must be at least 2 and at most 36. 643 | (optional) 644 |
  • 645 |
646 | 647 |

Returns:

648 |
    649 | 650 | A new bint or nil in case the conversion failed. 651 |
652 | 653 | 654 | 655 | 656 |
657 |
658 | 659 | fromstring (s) 660 |
661 |
662 | Create a new bint from a string. 663 | The string can by a decimal number, binary number prefixed with '0b' or hexadecimal number prefixed with '0x'. 664 | 665 | 666 |

Parameters:

667 |
    668 |
  • s 669 | A string convertible to a bint. 670 |
  • 671 |
672 | 673 |

Returns:

674 |
    675 | 676 | A new bint or nil in case the conversion failed. 677 |
678 | 679 | 680 |

See also:

681 | 684 | 685 | 686 |
687 |
688 | 689 | fromle (buffer) 690 |
691 |
692 | Create a new bint from a buffer of little-endian bytes. 693 | 694 | 695 |

Parameters:

696 |
    697 |
  • buffer 698 | Buffer of bytes, extra bytes are trimmed from the right, missing bytes are padded to the right. 699 |
  • 700 |
701 | 702 |

Returns:

703 |
    704 | 705 | A bint. 706 |
707 | 708 |

Raises:

709 | An assert is thrown in case buffer is not an string. 710 | 711 | 712 | 713 |
714 |
715 | 716 | frombe (buffer) 717 |
718 |
719 | Create a new bint from a buffer of big-endian bytes. 720 | 721 | 722 |

Parameters:

723 |
    724 |
  • buffer 725 | Buffer of bytes, extra bytes are trimmed from the left, missing bytes are padded to the left. 726 |
  • 727 |
728 | 729 |

Returns:

730 |
    731 | 732 | A bint. 733 |
734 | 735 |

Raises:

736 | An assert is thrown in case buffer is not an string. 737 | 738 | 739 | 740 |
741 |
742 | 743 | new (x) 744 |
745 |
746 | Create a new bint from a value. 747 | 748 | 749 |

Parameters:

750 |
    751 |
  • x 752 | A value convertible to a bint (string, number or another bint). 753 |
  • 754 |
755 | 756 |

Returns:

757 |
    758 | 759 | A new bint, guaranteed to be a new reference in case needed. 760 |
761 | 762 |

Raises:

763 | An assert is thrown in case x is not convertible to a bint. 764 | 765 |

See also:

766 | 770 | 771 | 772 |
773 |
774 | 775 | tobint (x[, clone]) 776 |
777 |
778 | Convert a value to a bint if possible. 779 | 780 | 781 |

Parameters:

782 |
    783 |
  • x 784 | A value to be converted (string, number or another bint). 785 |
  • 786 |
  • clone 787 | A boolean that tells if a new bint reference should be returned. 788 | Defaults to false. 789 | (optional) 790 |
  • 791 |
792 | 793 |

Returns:

794 |
    795 | 796 | A bint or nil in case the conversion failed. 797 |
798 | 799 | 800 |

See also:

801 | 805 | 806 | 807 |
808 |
809 | 810 | parse (x[, clone]) 811 |
812 |
813 | Convert a value to a bint if possible otherwise to a lua number. 814 | Useful to prepare values that you are unsure if it's going to be an integer or float. 815 | 816 | 817 |

Parameters:

818 |
    819 |
  • x 820 | A value to be converted (string, number or another bint). 821 |
  • 822 |
  • clone 823 | A boolean that tells if a new bint reference should be returned. 824 | Defaults to false. 825 | (optional) 826 |
  • 827 |
828 | 829 |

Returns:

830 |
    831 | 832 | A bint or a lua number or nil in case the conversion failed. 833 |
834 | 835 | 836 |

See also:

837 | 841 | 842 | 843 |
844 |
845 | 846 | touinteger (x) 847 |
848 |
849 | Convert a bint to an unsigned integer. 850 | Note that large unsigned integers may be represented as negatives in lua integers. 851 | Note that lua cannot represent values larger than 64 bits, 852 | in that case integer values wrap around. 853 | 854 | 855 |

Parameters:

856 |
    857 |
  • x 858 | A bint or a number to be converted into an unsigned integer. 859 |
  • 860 |
861 | 862 |

Returns:

863 |
    864 | 865 | An integer or nil in case the input cannot be represented by an integer. 866 |
867 | 868 | 869 |

See also:

870 | 873 | 874 | 875 |
876 |
877 | 878 | tointeger (x) 879 |
880 |
881 | Convert a bint to a signed integer. 882 | It works by taking absolute values then applying the sign bit in case needed. 883 | Note that lua cannot represent values larger than 64 bits, 884 | in that case integer values wrap around. 885 | 886 | 887 |

Parameters:

888 |
    889 |
  • x 890 | A bint or value to be converted into an unsigned integer. 891 |
  • 892 |
893 | 894 |

Returns:

895 |
    896 | 897 | An integer or nil in case the input cannot be represented by an integer. 898 |
899 | 900 | 901 |

See also:

902 | 905 | 906 | 907 |
908 |
909 | 910 | tonumber (x) 911 |
912 |
913 | Convert a bint to a lua float in case integer would wrap around or lua integer otherwise. 914 | Different from bint.tointeger the operation does not wrap around integers, 915 | but digits precision are lost in the process of converting to a float. 916 | 917 | 918 |

Parameters:

919 |
    920 |
  • x 921 | A bint or value to be converted into a lua number. 922 |
  • 923 |
924 | 925 |

Returns:

926 |
    927 | 928 | A lua number or nil in case the input cannot be represented by a number. 929 |
930 | 931 | 932 |

See also:

933 | 936 | 937 | 938 |
939 |
940 | 941 | tobase (x[, base[, unsigned]]) 942 |
943 |
944 | Convert a bint to a string in the desired base. 945 | 946 | 947 |

Parameters:

948 |
    949 |
  • x 950 | The bint to be converted from. 951 |
  • 952 |
  • base 953 | Base to be represented, defaults to 10. 954 | Must be at least 2 and at most 36. 955 | (optional) 956 |
  • 957 |
  • unsigned 958 | Whether to output as an unsigned integer. 959 | Defaults to false for base 10 and true for others. 960 | When unsigned is false the symbol '-' is prepended in negative values. 961 | (optional) 962 |
  • 963 |
964 | 965 |

Returns:

966 |
    967 | 968 | A string representing the input. 969 |
970 | 971 |

Raises:

972 | An assert is thrown in case the base is invalid. 973 | 974 | 975 | 976 |
977 |
978 | 979 | tole (x[, trim]) 980 |
981 |
982 | Convert a bint to a buffer of little-endian bytes. 983 | 984 | 985 |

Parameters:

986 |
    987 |
  • x 988 | A bint or lua integer. 989 |
  • 990 |
  • trim 991 | If true, zero bytes on the right are trimmed. 992 | (optional) 993 |
  • 994 |
995 | 996 |

Returns:

997 |
    998 | 999 | A buffer of bytes representing the input. 1000 |
1001 | 1002 |

Raises:

1003 | Asserts in case input is not convertible to an integer. 1004 | 1005 | 1006 | 1007 |
1008 |
1009 | 1010 | tobe (x[, trim]) 1011 |
1012 |
1013 | Convert a bint to a buffer of big-endian bytes. 1014 | 1015 | 1016 |

Parameters:

1017 |
    1018 |
  • x 1019 | A bint or lua integer. 1020 |
  • 1021 |
  • trim 1022 | If true, zero bytes on the left are trimmed. 1023 | (optional) 1024 |
  • 1025 |
1026 | 1027 |

Returns:

1028 |
    1029 | 1030 | A buffer of bytes representing the input. 1031 |
1032 | 1033 |

Raises:

1034 | Asserts in case input is not convertible to an integer. 1035 | 1036 | 1037 | 1038 |
1039 |
1040 | 1041 | iszero (x) 1042 |
1043 |
1044 | Check if a number is 0 considering bints. 1045 | 1046 | 1047 |

Parameters:

1048 |
    1049 |
  • x 1050 | A bint or a lua number. 1051 |
  • 1052 |
1053 | 1054 | 1055 | 1056 | 1057 | 1058 |
1059 |
1060 | 1061 | isone (x) 1062 |
1063 |
1064 | Check if a number is 1 considering bints. 1065 | 1066 | 1067 |

Parameters:

1068 |
    1069 |
  • x 1070 | A bint or a lua number. 1071 |
  • 1072 |
1073 | 1074 | 1075 | 1076 | 1077 | 1078 |
1079 |
1080 | 1081 | isminusone (x) 1082 |
1083 |
1084 | Check if a number is -1 considering bints. 1085 | 1086 | 1087 |

Parameters:

1088 |
    1089 |
  • x 1090 | A bint or a lua number. 1091 |
  • 1092 |
1093 | 1094 | 1095 | 1096 | 1097 | 1098 |
1099 |
1100 | 1101 | isbint (x) 1102 |
1103 |
1104 | Check if the input is a bint. 1105 | 1106 | 1107 |

Parameters:

1108 |
    1109 |
  • x 1110 | Any lua value. 1111 |
  • 1112 |
1113 | 1114 | 1115 | 1116 | 1117 | 1118 |
1119 |
1120 | 1121 | isintegral (x) 1122 |
1123 |
1124 | Check if the input is a lua integer or a bint. 1125 | 1126 | 1127 |

Parameters:

1128 |
    1129 |
  • x 1130 | Any lua value. 1131 |
  • 1132 |
1133 | 1134 | 1135 | 1136 | 1137 | 1138 |
1139 |
1140 | 1141 | isnumeric (x) 1142 |
1143 |
1144 | Check if the input is a bint or a lua number. 1145 | 1146 | 1147 |

Parameters:

1148 |
    1149 |
  • x 1150 | Any lua value. 1151 |
  • 1152 |
1153 | 1154 | 1155 | 1156 | 1157 | 1158 |
1159 |
1160 | 1161 | type (x) 1162 |
1163 |
1164 | Get the number type of the input (bint, integer or float). 1165 | 1166 | 1167 |

Parameters:

1168 |
    1169 |
  • x 1170 | Any lua value. 1171 |
  • 1172 |
1173 | 1174 |

Returns:

1175 |
    1176 | 1177 | Returns "bint" for bints, "integer" for lua integers, 1178 | "float" from lua floats or nil otherwise. 1179 |
1180 | 1181 | 1182 | 1183 | 1184 |
1185 |
1186 | 1187 | isneg (x) 1188 |
1189 |
1190 | Check if a number is negative considering bints. 1191 | Zero is guaranteed to never be negative for bints. 1192 | 1193 | 1194 |

Parameters:

1195 |
    1196 |
  • x 1197 | A bint or a lua number. 1198 |
  • 1199 |
1200 | 1201 | 1202 | 1203 | 1204 | 1205 |
1206 |
1207 | 1208 | ispos (x) 1209 |
1210 |
1211 | Check if a number is positive considering bints. 1212 | 1213 | 1214 |

Parameters:

1215 |
    1216 |
  • x 1217 | A bint or a lua number. 1218 |
  • 1219 |
1220 | 1221 | 1222 | 1223 | 1224 | 1225 |
1226 |
1227 | 1228 | iseven (x) 1229 |
1230 |
1231 | Check if a number is even considering bints. 1232 | 1233 | 1234 |

Parameters:

1235 |
    1236 |
  • x 1237 | A bint or a lua number. 1238 |
  • 1239 |
1240 | 1241 | 1242 | 1243 | 1244 | 1245 |
1246 |
1247 | 1248 | isodd (x) 1249 |
1250 |
1251 | Check if a number is odd considering bints. 1252 | 1253 | 1254 |

Parameters:

1255 |
    1256 |
  • x 1257 | A bint or a lua number. 1258 |
  • 1259 |
1260 | 1261 | 1262 | 1263 | 1264 | 1265 |
1266 |
1267 | 1268 | maxinteger () 1269 |
1270 |
1271 | Create a new bint with the maximum possible integer value. 1272 | 1273 | 1274 | 1275 | 1276 | 1277 | 1278 | 1279 |
1280 |
1281 | 1282 | mininteger () 1283 |
1284 |
1285 | Create a new bint with the minimum possible integer value. 1286 | 1287 | 1288 | 1289 | 1290 | 1291 | 1292 | 1293 |
1294 |
1295 | 1296 | _shlone () 1297 |
1298 |
1299 | Bitwise left shift a bint in one bit (in-place). 1300 | 1301 | 1302 | 1303 | 1304 | 1305 | 1306 | 1307 |
1308 |
1309 | 1310 | _shrone () 1311 |
1312 |
1313 | Bitwise right shift a bint in one bit (in-place). 1314 | 1315 | 1316 | 1317 | 1318 | 1319 | 1320 | 1321 |
1322 |
1323 | 1324 | _inc () 1325 |
1326 |
1327 | Increment a bint by one (in-place). 1328 | 1329 | 1330 | 1331 | 1332 | 1333 | 1334 | 1335 |
1336 |
1337 | 1338 | inc (x) 1339 |
1340 |
1341 | Increment a number by one considering bints. 1342 | 1343 | 1344 |

Parameters:

1345 |
    1346 |
  • x 1347 | A bint or a lua number to increment. 1348 |
  • 1349 |
1350 | 1351 | 1352 | 1353 | 1354 | 1355 |
1356 |
1357 | 1358 | _dec () 1359 |
1360 |
1361 | Decrement a bint by one (in-place). 1362 | 1363 | 1364 | 1365 | 1366 | 1367 | 1368 | 1369 |
1370 |
1371 | 1372 | dec (x) 1373 |
1374 |
1375 | Decrement a number by one considering bints. 1376 | 1377 | 1378 |

Parameters:

1379 |
    1380 |
  • x 1381 | A bint or a lua number to decrement. 1382 |
  • 1383 |
1384 | 1385 | 1386 | 1387 | 1388 | 1389 |
1390 |
1391 | 1392 | _assign (y) 1393 |
1394 |
1395 | Assign a bint to a new value (in-place). 1396 | 1397 | 1398 |

Parameters:

1399 |
    1400 |
  • y 1401 | A value to be copied from. 1402 |
  • 1403 |
1404 | 1405 | 1406 |

Raises:

1407 | Asserts in case inputs are not convertible to integers. 1408 | 1409 | 1410 | 1411 |
1412 |
1413 | 1414 | _abs () 1415 |
1416 |
1417 | Take absolute of a bint (in-place). 1418 | 1419 | 1420 | 1421 | 1422 | 1423 | 1424 | 1425 |
1426 |
1427 | 1428 | abs (x) 1429 |
1430 |
1431 | Take absolute of a number considering bints. 1432 | 1433 | 1434 |

Parameters:

1435 |
    1436 |
  • x 1437 | A bint or a lua number to take the absolute. 1438 |
  • 1439 |
1440 | 1441 | 1442 | 1443 | 1444 | 1445 |
1446 |
1447 | 1448 | floor (x) 1449 |
1450 |
1451 | Take the floor of a number considering bints. 1452 | 1453 | 1454 |

Parameters:

1455 |
    1456 |
  • x 1457 | A bint or a lua number to perform the floor operation. 1458 |
  • 1459 |
1460 | 1461 | 1462 | 1463 | 1464 | 1465 |
1466 |
1467 | 1468 | ceil (x) 1469 |
1470 |
1471 | Take ceil of a number considering bints. 1472 | 1473 | 1474 |

Parameters:

1475 |
    1476 |
  • x 1477 | A bint or a lua number to perform the ceil operation. 1478 |
  • 1479 |
1480 | 1481 | 1482 | 1483 | 1484 | 1485 |
1486 |
1487 | 1488 | bwrap (x, y) 1489 |
1490 |
1491 | Wrap around bits of an integer (discarding left bits) considering bints. 1492 | 1493 | 1494 |

Parameters:

1495 |
    1496 |
  • x 1497 | A bint or a lua integer. 1498 |
  • 1499 |
  • y 1500 | Number of right bits to preserve. 1501 |
  • 1502 |
1503 | 1504 | 1505 | 1506 | 1507 | 1508 |
1509 |
1510 | 1511 | brol (x, y) 1512 |
1513 |
1514 | Rotate left integer x by y bits considering bints. 1515 | 1516 | 1517 |

Parameters:

1518 |
    1519 |
  • x 1520 | A bint or a lua integer. 1521 |
  • 1522 |
  • y 1523 | Number of bits to rotate. 1524 |
  • 1525 |
1526 | 1527 | 1528 | 1529 | 1530 | 1531 |
1532 |
1533 | 1534 | bror (x, y) 1535 |
1536 |
1537 | Rotate right integer x by y bits considering bints. 1538 | 1539 | 1540 |

Parameters:

1541 |
    1542 |
  • x 1543 | A bint or a lua integer. 1544 |
  • 1545 |
  • y 1546 | Number of bits to rotate. 1547 |
  • 1548 |
1549 | 1550 | 1551 | 1552 | 1553 | 1554 |
1555 |
1556 | 1557 | trunc (x) 1558 |
1559 |
1560 | Truncate a number to a bint. 1561 | Floats numbers are truncated, that is, the fractional port is discarded. 1562 | 1563 | 1564 |

Parameters:

1565 |
    1566 |
  • x 1567 | A number to truncate. 1568 |
  • 1569 |
1570 | 1571 |

Returns:

1572 |
    1573 | 1574 | A new bint or nil in case the input does not fit in a bint or is not a number. 1575 |
1576 | 1577 | 1578 | 1579 | 1580 |
1581 |
1582 | 1583 | max (x, y) 1584 |
1585 |
1586 | Take maximum between two numbers considering bints. 1587 | 1588 | 1589 |

Parameters:

1590 |
    1591 |
  • x 1592 | A bint or lua number to compare. 1593 |
  • 1594 |
  • y 1595 | A bint or lua number to compare. 1596 |
  • 1597 |
1598 | 1599 |

Returns:

1600 |
    1601 | 1602 | A bint or a lua number. Guarantees to return a new bint for integer values. 1603 |
1604 | 1605 | 1606 | 1607 | 1608 |
1609 |
1610 | 1611 | min (x, y) 1612 |
1613 |
1614 | Take minimum between two numbers considering bints. 1615 | 1616 | 1617 |

Parameters:

1618 |
    1619 |
  • x 1620 | A bint or lua number to compare. 1621 |
  • 1622 |
  • y 1623 | A bint or lua number to compare. 1624 |
  • 1625 |
1626 | 1627 |

Returns:

1628 |
    1629 | 1630 | A bint or a lua number. Guarantees to return a new bint for integer values. 1631 |
1632 | 1633 | 1634 | 1635 | 1636 |
1637 |
1638 | 1639 | _add (y) 1640 |
1641 |
1642 | Add an integer to a bint (in-place). 1643 | 1644 | 1645 |

Parameters:

1646 |
    1647 |
  • y 1648 | An integer to be added. 1649 |
  • 1650 |
1651 | 1652 | 1653 |

Raises:

1654 | Asserts in case inputs are not convertible to integers. 1655 | 1656 | 1657 | 1658 |
1659 |
1660 | 1661 | __add (x, y) 1662 |
1663 |
1664 | Add two numbers considering bints. 1665 | 1666 | 1667 |

Parameters:

1668 |
    1669 |
  • x 1670 | A bint or a lua number to be added. 1671 |
  • 1672 |
  • y 1673 | A bint or a lua number to be added. 1674 |
  • 1675 |
1676 | 1677 | 1678 | 1679 | 1680 | 1681 |
1682 |
1683 | 1684 | _sub (y) 1685 |
1686 |
1687 | Subtract an integer from a bint (in-place). 1688 | 1689 | 1690 |

Parameters:

1691 |
    1692 |
  • y 1693 | An integer to subtract. 1694 |
  • 1695 |
1696 | 1697 | 1698 |

Raises:

1699 | Asserts in case inputs are not convertible to integers. 1700 | 1701 | 1702 | 1703 |
1704 |
1705 | 1706 | __sub (x, y) 1707 |
1708 |
1709 | Subtract two numbers considering bints. 1710 | 1711 | 1712 |

Parameters:

1713 |
    1714 |
  • x 1715 | A bint or a lua number to be subtracted from. 1716 |
  • 1717 |
  • y 1718 | A bint or a lua number to subtract. 1719 |
  • 1720 |
1721 | 1722 | 1723 | 1724 | 1725 | 1726 |
1727 |
1728 | 1729 | __mul (x, y) 1730 |
1731 |
1732 | Multiply two numbers considering bints. 1733 | 1734 | 1735 |

Parameters:

1736 |
    1737 |
  • x 1738 | A bint or a lua number to multiply. 1739 |
  • 1740 |
  • y 1741 | A bint or a lua number to multiply. 1742 |
  • 1743 |
1744 | 1745 | 1746 | 1747 | 1748 | 1749 |
1750 |
1751 | 1752 | __eq (x, y) 1753 |
1754 |
1755 | Check if bints are equal. 1756 | 1757 | 1758 |

Parameters:

1759 |
    1760 |
  • x 1761 | A bint to compare. 1762 |
  • 1763 |
  • y 1764 | A bint to compare. 1765 |
  • 1766 |
1767 | 1768 | 1769 | 1770 | 1771 | 1772 |
1773 |
1774 | 1775 | eq (x, y) 1776 |
1777 |
1778 | Check if numbers are equal considering bints. 1779 | 1780 | 1781 |

Parameters:

1782 |
    1783 |
  • x 1784 | A bint or lua number to compare. 1785 |
  • 1786 |
  • y 1787 | A bint or lua number to compare. 1788 |
  • 1789 |
1790 | 1791 | 1792 | 1793 | 1794 | 1795 |
1796 |
1797 | 1798 | udivmod (x, y) 1799 |
1800 |
1801 | Perform unsigned division and modulo operation between two integers considering bints. 1802 | This is effectively the same of bint.udiv and bint.umod. 1803 | 1804 | 1805 |

Parameters:

1806 |
    1807 |
  • x 1808 | The numerator, must be a bint or a lua integer. 1809 |
  • 1810 |
  • y 1811 | The denominator, must be a bint or a lua integer. 1812 |
  • 1813 |
1814 | 1815 |

Returns:

1816 |
    1817 | 1818 | The quotient following the remainder, both bints. 1819 |
1820 | 1821 |

Raises:

1822 | Asserts on attempt to divide by zero 1823 | or if inputs are not convertible to integers. 1824 | 1825 |

See also:

1826 | 1830 | 1831 | 1832 |
1833 |
1834 | 1835 | udiv (x, y) 1836 |
1837 |
1838 | Perform unsigned division between two integers considering bints. 1839 | 1840 | 1841 |

Parameters:

1842 |
    1843 |
  • x 1844 | The numerator, must be a bint or a lua integer. 1845 |
  • 1846 |
  • y 1847 | The denominator, must be a bint or a lua integer. 1848 |
  • 1849 |
1850 | 1851 |

Returns:

1852 |
    1853 | 1854 | The quotient, a bint. 1855 |
1856 | 1857 |

Raises:

1858 | Asserts on attempt to divide by zero 1859 | or if inputs are not convertible to integers. 1860 | 1861 | 1862 | 1863 |
1864 |
1865 | 1866 | umod (x, y) 1867 |
1868 |
1869 | Perform unsigned integer modulo operation between two integers considering bints. 1870 | 1871 | 1872 |

Parameters:

1873 |
    1874 |
  • x 1875 | The numerator, must be a bint or a lua integer. 1876 |
  • 1877 |
  • y 1878 | The denominator, must be a bint or a lua integer. 1879 |
  • 1880 |
1881 | 1882 |

Returns:

1883 |
    1884 | 1885 | The remainder, a bint. 1886 |
1887 | 1888 |

Raises:

1889 | Asserts on attempt to divide by zero 1890 | or if the inputs are not convertible to integers. 1891 | 1892 | 1893 | 1894 |
1895 |
1896 | 1897 | tdivmod (x, y) 1898 |
1899 |
1900 | Perform integer truncate division and modulo operation between two numbers considering bints. 1901 | This is effectively the same of bint.tdiv and bint.tmod. 1902 | 1903 | 1904 |

Parameters:

1905 |
    1906 |
  • x 1907 | The numerator, a bint or lua number. 1908 |
  • 1909 |
  • y 1910 | The denominator, a bint or lua number. 1911 |
  • 1912 |
1913 | 1914 |

Returns:

1915 |
    1916 | 1917 | The quotient following the remainder, both bint or lua number. 1918 |
1919 | 1920 |

Raises:

1921 | Asserts on attempt to divide by zero or on division overflow. 1922 | 1923 |

See also:

1924 | 1928 | 1929 | 1930 |
1931 |
1932 | 1933 | tdiv (x, y) 1934 |
1935 |
1936 | Perform truncate division between two numbers considering bints. 1937 | Truncate division is a division that rounds the quotient towards zero. 1938 | 1939 | 1940 |

Parameters:

1941 |
    1942 |
  • x 1943 | The numerator, a bint or lua number. 1944 |
  • 1945 |
  • y 1946 | The denominator, a bint or lua number. 1947 |
  • 1948 |
1949 | 1950 |

Returns:

1951 |
    1952 | 1953 | The quotient, a bint or lua number. 1954 |
1955 | 1956 |

Raises:

1957 | Asserts on attempt to divide by zero or on division overflow. 1958 | 1959 | 1960 | 1961 |
1962 |
1963 | 1964 | tmod (x, y) 1965 |
1966 |
1967 | Perform integer truncate modulo operation between two numbers considering bints. 1968 | The operation is defined as the remainder of the truncate division 1969 | (division that rounds the quotient towards zero). 1970 | 1971 | 1972 |

Parameters:

1973 |
    1974 |
  • x 1975 | The numerator, a bint or lua number. 1976 |
  • 1977 |
  • y 1978 | The denominator, a bint or lua number. 1979 |
  • 1980 |
1981 | 1982 |

Returns:

1983 |
    1984 | 1985 | The remainder, a bint or lua number. 1986 |
1987 | 1988 |

Raises:

1989 | Asserts on attempt to divide by zero or on division overflow. 1990 | 1991 | 1992 | 1993 |
1994 |
1995 | 1996 | idivmod (x, y) 1997 |
1998 |
1999 | Perform integer floor division and modulo operation between two numbers considering bints. 2000 | This is effectively the same of bint.__idiv and bint.__mod. 2001 | 2002 | 2003 |

Parameters:

2004 |
    2005 |
  • x 2006 | The numerator, a bint or lua number. 2007 |
  • 2008 |
  • y 2009 | The denominator, a bint or lua number. 2010 |
  • 2011 |
2012 | 2013 |

Returns:

2014 |
    2015 | 2016 | The quotient following the remainder, both bint or lua number. 2017 |
2018 | 2019 |

Raises:

2020 | Asserts on attempt to divide by zero. 2021 | 2022 |

See also:

2023 | 2027 | 2028 | 2029 |
2030 |
2031 | 2032 | __idiv (x, y) 2033 |
2034 |
2035 | Perform floor division between two numbers considering bints. 2036 | Floor division is a division that rounds the quotient towards minus infinity, 2037 | resulting in the floor of the division of its operands. 2038 | 2039 | 2040 |

Parameters:

2041 |
    2042 |
  • x 2043 | The numerator, a bint or lua number. 2044 |
  • 2045 |
  • y 2046 | The denominator, a bint or lua number. 2047 |
  • 2048 |
2049 | 2050 |

Returns:

2051 |
    2052 | 2053 | The quotient, a bint or lua number. 2054 |
2055 | 2056 |

Raises:

2057 | Asserts on attempt to divide by zero. 2058 | 2059 | 2060 | 2061 |
2062 |
2063 | 2064 | __div (x, y) 2065 |
2066 |
2067 | Perform division between two numbers considering bints. 2068 | This always casts inputs to floats, for integer division only use bint.__idiv. 2069 | 2070 | 2071 |

Parameters:

2072 |
    2073 |
  • x 2074 | The numerator, a bint or lua number. 2075 |
  • 2076 |
  • y 2077 | The denominator, a bint or lua number. 2078 |
  • 2079 |
2080 | 2081 |

Returns:

2082 |
    2083 | 2084 | The quotient, a lua number. 2085 |
2086 | 2087 | 2088 | 2089 | 2090 |
2091 |
2092 | 2093 | __mod (x, y) 2094 |
2095 |
2096 | Perform integer floor modulo operation between two numbers considering bints. 2097 | The operation is defined as the remainder of the floor division 2098 | (division that rounds the quotient towards minus infinity). 2099 | 2100 | 2101 |

Parameters:

2102 |
    2103 |
  • x 2104 | The numerator, a bint or lua number. 2105 |
  • 2106 |
  • y 2107 | The denominator, a bint or lua number. 2108 |
  • 2109 |
2110 | 2111 |

Returns:

2112 |
    2113 | 2114 | The remainder, a bint or lua number. 2115 |
2116 | 2117 |

Raises:

2118 | Asserts on attempt to divide by zero. 2119 | 2120 | 2121 | 2122 |
2123 |
2124 | 2125 | ipow (x, y) 2126 |
2127 |
2128 | Perform integer power between two integers considering bints. 2129 | If y is negative then pow is performed as an unsigned integer. 2130 | 2131 | 2132 |

Parameters:

2133 |
    2134 |
  • x 2135 | The base, an integer. 2136 |
  • 2137 |
  • y 2138 | The exponent, an integer. 2139 |
  • 2140 |
2141 | 2142 |

Returns:

2143 |
    2144 | 2145 | The result of the pow operation, a bint. 2146 |
2147 | 2148 |

Raises:

2149 | Asserts in case inputs are not convertible to integers. 2150 | 2151 |

See also:

2152 | 2156 | 2157 | 2158 |
2159 |
2160 | 2161 | upowmod (x, y, m) 2162 |
2163 |
2164 | Perform integer power between two unsigned integers over a modulus considering bints. 2165 | 2166 | 2167 |

Parameters:

2168 |
    2169 |
  • x 2170 | The base, an integer. 2171 |
  • 2172 |
  • y 2173 | The exponent, an integer. 2174 |
  • 2175 |
  • m 2176 | The modulus, an integer. 2177 |
  • 2178 |
2179 | 2180 |

Returns:

2181 |
    2182 | 2183 | The result of the pow operation, a bint. 2184 |
2185 | 2186 |

Raises:

2187 | Asserts in case inputs are not convertible to integers. 2188 | 2189 |

See also:

2190 | 2194 | 2195 | 2196 |
2197 |
2198 | 2199 | __pow (x, y) 2200 |
2201 |
2202 | Perform numeric power between two numbers considering bints. 2203 | This always casts inputs to floats, for integer power only use bint.ipow. 2204 | 2205 | 2206 |

Parameters:

2207 |
    2208 |
  • x 2209 | The base, a bint or lua number. 2210 |
  • 2211 |
  • y 2212 | The exponent, a bint or lua number. 2213 |
  • 2214 |
2215 | 2216 |

Returns:

2217 |
    2218 | 2219 | The result of the pow operation, a lua number. 2220 |
2221 | 2222 | 2223 |

See also:

2224 | 2227 | 2228 | 2229 |
2230 |
2231 | 2232 | __shl (x, y) 2233 |
2234 |
2235 | Bitwise left shift integers considering bints. 2236 | 2237 | 2238 |

Parameters:

2239 |
    2240 |
  • x 2241 | An integer to perform the bitwise shift. 2242 |
  • 2243 |
  • y 2244 | An integer with the number of bits to shift. 2245 |
  • 2246 |
2247 | 2248 |

Returns:

2249 |
    2250 | 2251 | The result of shift operation, a bint. 2252 |
2253 | 2254 |

Raises:

2255 | Asserts in case inputs are not convertible to integers. 2256 | 2257 | 2258 | 2259 |
2260 |
2261 | 2262 | __shr (x, y) 2263 |
2264 |
2265 | Bitwise right shift integers considering bints. 2266 | 2267 | 2268 |

Parameters:

2269 |
    2270 |
  • x 2271 | An integer to perform the bitwise shift. 2272 |
  • 2273 |
  • y 2274 | An integer with the number of bits to shift. 2275 |
  • 2276 |
2277 | 2278 |

Returns:

2279 |
    2280 | 2281 | The result of shift operation, a bint. 2282 |
2283 | 2284 |

Raises:

2285 | Asserts in case inputs are not convertible to integers. 2286 | 2287 | 2288 | 2289 |
2290 |
2291 | 2292 | _band (y) 2293 |
2294 |
2295 | Bitwise AND bints (in-place). 2296 | 2297 | 2298 |

Parameters:

2299 |
    2300 |
  • y 2301 | An integer to perform bitwise AND. 2302 |
  • 2303 |
2304 | 2305 | 2306 |

Raises:

2307 | Asserts in case inputs are not convertible to integers. 2308 | 2309 | 2310 | 2311 |
2312 |
2313 | 2314 | __band (x, y) 2315 |
2316 |
2317 | Bitwise AND two integers considering bints. 2318 | 2319 | 2320 |

Parameters:

2321 |
    2322 |
  • x 2323 | An integer to perform bitwise AND. 2324 |
  • 2325 |
  • y 2326 | An integer to perform bitwise AND. 2327 |
  • 2328 |
2329 | 2330 | 2331 |

Raises:

2332 | Asserts in case inputs are not convertible to integers. 2333 | 2334 | 2335 | 2336 |
2337 |
2338 | 2339 | _bor (y) 2340 |
2341 |
2342 | Bitwise OR bints (in-place). 2343 | 2344 | 2345 |

Parameters:

2346 |
    2347 |
  • y 2348 | An integer to perform bitwise OR. 2349 |
  • 2350 |
2351 | 2352 | 2353 |

Raises:

2354 | Asserts in case inputs are not convertible to integers. 2355 | 2356 | 2357 | 2358 |
2359 |
2360 | 2361 | __bor (x, y) 2362 |
2363 |
2364 | Bitwise OR two integers considering bints. 2365 | 2366 | 2367 |

Parameters:

2368 |
    2369 |
  • x 2370 | An integer to perform bitwise OR. 2371 |
  • 2372 |
  • y 2373 | An integer to perform bitwise OR. 2374 |
  • 2375 |
2376 | 2377 | 2378 |

Raises:

2379 | Asserts in case inputs are not convertible to integers. 2380 | 2381 | 2382 | 2383 |
2384 |
2385 | 2386 | _bxor (y) 2387 |
2388 |
2389 | Bitwise XOR bints (in-place). 2390 | 2391 | 2392 |

Parameters:

2393 |
    2394 |
  • y 2395 | An integer to perform bitwise XOR. 2396 |
  • 2397 |
2398 | 2399 | 2400 |

Raises:

2401 | Asserts in case inputs are not convertible to integers. 2402 | 2403 | 2404 | 2405 |
2406 |
2407 | 2408 | __bxor (x, y) 2409 |
2410 |
2411 | Bitwise XOR two integers considering bints. 2412 | 2413 | 2414 |

Parameters:

2415 |
    2416 |
  • x 2417 | An integer to perform bitwise XOR. 2418 |
  • 2419 |
  • y 2420 | An integer to perform bitwise XOR. 2421 |
  • 2422 |
2423 | 2424 | 2425 |

Raises:

2426 | Asserts in case inputs are not convertible to integers. 2427 | 2428 | 2429 | 2430 |
2431 |
2432 | 2433 | _bnot () 2434 |
2435 |
2436 | Bitwise NOT a bint (in-place). 2437 | 2438 | 2439 | 2440 | 2441 | 2442 | 2443 | 2444 |
2445 |
2446 | 2447 | __bnot (x) 2448 |
2449 |
2450 | Bitwise NOT a bint. 2451 | 2452 | 2453 |

Parameters:

2454 |
    2455 |
  • x 2456 | An integer to perform bitwise NOT. 2457 |
  • 2458 |
2459 | 2460 | 2461 |

Raises:

2462 | Asserts in case inputs are not convertible to integers. 2463 | 2464 | 2465 | 2466 |
2467 |
2468 | 2469 | _unm () 2470 |
2471 |
2472 | Negate a bint (in-place). This effectively applies two's complements. 2473 | 2474 | 2475 | 2476 | 2477 | 2478 | 2479 | 2480 |
2481 |
2482 | 2483 | __unm (x) 2484 |
2485 |
2486 | Negate a bint. This effectively applies two's complements. 2487 | 2488 | 2489 |

Parameters:

2490 |
    2491 |
  • x 2492 | A bint to perform negation. 2493 |
  • 2494 |
2495 | 2496 | 2497 | 2498 | 2499 | 2500 |
2501 |
2502 | 2503 | ult (x, y) 2504 |
2505 |
2506 | Compare if integer x is less than y considering bints (unsigned version). 2507 | 2508 | 2509 |

Parameters:

2510 |
    2511 |
  • x 2512 | Left integer to compare. 2513 |
  • 2514 |
  • y 2515 | Right integer to compare. 2516 |
  • 2517 |
2518 | 2519 | 2520 |

Raises:

2521 | Asserts in case inputs are not convertible to integers. 2522 | 2523 |

See also:

2524 | 2527 | 2528 | 2529 |
2530 |
2531 | 2532 | ule (x, y) 2533 |
2534 |
2535 | Compare if bint x is less or equal than y considering bints (unsigned version). 2536 | 2537 | 2538 |

Parameters:

2539 |
    2540 |
  • x 2541 | Left integer to compare. 2542 |
  • 2543 |
  • y 2544 | Right integer to compare. 2545 |
  • 2546 |
2547 | 2548 | 2549 |

Raises:

2550 | Asserts in case inputs are not convertible to integers. 2551 | 2552 |

See also:

2553 | 2556 | 2557 | 2558 |
2559 |
2560 | 2561 | __lt (x, y) 2562 |
2563 |
2564 | Compare if number x is less than y considering bints and signs. 2565 | 2566 | 2567 |

Parameters:

2568 |
    2569 |
  • x 2570 | Left value to compare, a bint or lua number. 2571 |
  • 2572 |
  • y 2573 | Right value to compare, a bint or lua number. 2574 |
  • 2575 |
2576 | 2577 | 2578 | 2579 |

See also:

2580 | 2583 | 2584 | 2585 |
2586 |
2587 | 2588 | __le (x, y) 2589 |
2590 |
2591 | Compare if number x is less or equal than y considering bints and signs. 2592 | 2593 | 2594 |

Parameters:

2595 |
    2596 |
  • x 2597 | Left value to compare, a bint or lua number. 2598 |
  • 2599 |
  • y 2600 | Right value to compare, a bint or lua number. 2601 |
  • 2602 |
2603 | 2604 | 2605 | 2606 |

See also:

2607 | 2610 | 2611 | 2612 |
2613 |
2614 | 2615 | __tostring () 2616 |
2617 |
2618 | Convert a bint to a string on base 10. 2619 | 2620 | 2621 | 2622 | 2623 | 2624 |

See also:

2625 | 2628 | 2629 | 2630 |
2631 |
2632 |

Fields

2633 | 2634 |
2635 |
2636 | 2637 | bits 2638 |
2639 |
2640 | Number of bits representing a bint instance. 2641 | 2642 | 2643 | 2644 | 2645 | 2646 | 2647 | 2648 |
2649 |
2650 | 2651 | 2652 |
2653 |
2654 |
2655 | generated by LDoc 1.5.0 2656 | Last updated 2024-10-30 08:39:35 2657 |
2658 |
2659 | 2660 | 2661 | -------------------------------------------------------------------------------- /docs/ldoc.css: -------------------------------------------------------------------------------- 1 | /* BEGIN RESET 2 | 3 | Copyright (c) 2010, Yahoo! Inc. All rights reserved. 4 | Code licensed under the BSD License: 5 | http://developer.yahoo.com/yui/license.html 6 | version: 2.8.2r1 7 | */ 8 | html { 9 | color: #000; 10 | background: #FFF; 11 | } 12 | body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td { 13 | margin: 0; 14 | padding: 0; 15 | } 16 | table { 17 | border-collapse: collapse; 18 | border-spacing: 0; 19 | } 20 | fieldset,img { 21 | border: 0; 22 | } 23 | address,caption,cite,code,dfn,em,strong,th,var,optgroup { 24 | font-style: inherit; 25 | font-weight: inherit; 26 | } 27 | del,ins { 28 | text-decoration: none; 29 | } 30 | li { 31 | margin-left: 20px; 32 | } 33 | caption,th { 34 | text-align: left; 35 | } 36 | h1,h2,h3,h4,h5,h6 { 37 | font-size: 100%; 38 | font-weight: bold; 39 | } 40 | q:before,q:after { 41 | content: ''; 42 | } 43 | abbr,acronym { 44 | border: 0; 45 | font-variant: normal; 46 | } 47 | sup { 48 | vertical-align: baseline; 49 | } 50 | sub { 51 | vertical-align: baseline; 52 | } 53 | legend { 54 | color: #000; 55 | } 56 | input,button,textarea,select,optgroup,option { 57 | font-family: inherit; 58 | font-size: inherit; 59 | font-style: inherit; 60 | font-weight: inherit; 61 | } 62 | input,button,textarea,select {*font-size:100%; 63 | } 64 | /* END RESET */ 65 | 66 | body { 67 | margin-left: 1em; 68 | margin-right: 1em; 69 | font-family: arial, helvetica, geneva, sans-serif; 70 | background-color: #ffffff; margin: 0px; 71 | } 72 | 73 | code, tt { font-family: monospace; font-size: 1.1em; } 74 | span.parameter { font-family:monospace; } 75 | span.parameter:after { content:":"; } 76 | span.types:before { content:"("; } 77 | span.types:after { content:")"; } 78 | .type { font-weight: bold; font-style:italic } 79 | 80 | body, p, td, th { font-size: .95em; line-height: 1.2em;} 81 | 82 | p, ul { margin: 10px 0 0 0px;} 83 | 84 | strong { font-weight: bold;} 85 | 86 | em { font-style: italic;} 87 | 88 | h1 { 89 | font-size: 1.5em; 90 | margin: 20px 0 20px 0; 91 | } 92 | h2, h3, h4 { margin: 15px 0 10px 0; } 93 | h2 { font-size: 1.25em; } 94 | h3 { font-size: 1.15em; } 95 | h4 { font-size: 1.06em; } 96 | 97 | a:link { font-weight: bold; color: #004080; text-decoration: none; } 98 | a:visited { font-weight: bold; color: #006699; text-decoration: none; } 99 | a:link:hover { text-decoration: underline; } 100 | 101 | hr { 102 | color:#cccccc; 103 | background: #00007f; 104 | height: 1px; 105 | } 106 | 107 | blockquote { margin-left: 3em; } 108 | 109 | ul { list-style-type: disc; } 110 | 111 | p.name { 112 | font-family: "Andale Mono", monospace; 113 | padding-top: 1em; 114 | } 115 | 116 | pre { 117 | background-color: rgb(245, 245, 245); 118 | border: 1px solid #C0C0C0; /* silver */ 119 | padding: 10px; 120 | margin: 10px 0 10px 0; 121 | overflow: auto; 122 | font-family: "Andale Mono", monospace; 123 | } 124 | 125 | pre.example { 126 | font-size: .85em; 127 | } 128 | 129 | table.index { border: 1px #00007f; } 130 | table.index td { text-align: left; vertical-align: top; } 131 | 132 | #container { 133 | margin-left: 1em; 134 | margin-right: 1em; 135 | background-color: #f0f0f0; 136 | } 137 | 138 | #product { 139 | text-align: center; 140 | border-bottom: 1px solid #cccccc; 141 | background-color: #ffffff; 142 | } 143 | 144 | #product big { 145 | font-size: 2em; 146 | } 147 | 148 | #main { 149 | background-color: #f0f0f0; 150 | border-left: 2px solid #cccccc; 151 | } 152 | 153 | #navigation { 154 | float: left; 155 | width: 14em; 156 | vertical-align: top; 157 | background-color: #f0f0f0; 158 | overflow: visible; 159 | } 160 | 161 | #navigation h2 { 162 | background-color:#e7e7e7; 163 | font-size:1.1em; 164 | color:#000000; 165 | text-align: left; 166 | padding:0.2em; 167 | border-top:1px solid #dddddd; 168 | border-bottom:1px solid #dddddd; 169 | } 170 | 171 | #navigation ul 172 | { 173 | font-size:1em; 174 | list-style-type: none; 175 | margin: 1px 1px 10px 1px; 176 | } 177 | 178 | #navigation li { 179 | text-indent: -1em; 180 | display: block; 181 | margin: 3px 0px 0px 22px; 182 | } 183 | 184 | #navigation li li a { 185 | margin: 0px 3px 0px -1em; 186 | } 187 | 188 | #content { 189 | margin-left: 14em; 190 | padding: 1em; 191 | width: 700px; 192 | border-left: 2px solid #cccccc; 193 | border-right: 2px solid #cccccc; 194 | background-color: #ffffff; 195 | } 196 | 197 | #about { 198 | clear: both; 199 | padding: 5px; 200 | border-top: 2px solid #cccccc; 201 | background-color: #ffffff; 202 | } 203 | 204 | @media print { 205 | body { 206 | font: 12pt "Times New Roman", "TimeNR", Times, serif; 207 | } 208 | a { font-weight: bold; color: #004080; text-decoration: underline; } 209 | 210 | #main { 211 | background-color: #ffffff; 212 | border-left: 0px; 213 | } 214 | 215 | #container { 216 | margin-left: 2%; 217 | margin-right: 2%; 218 | background-color: #ffffff; 219 | } 220 | 221 | #content { 222 | padding: 1em; 223 | background-color: #ffffff; 224 | } 225 | 226 | #navigation { 227 | display: none; 228 | } 229 | pre.example { 230 | font-family: "Andale Mono", monospace; 231 | font-size: 10pt; 232 | page-break-inside: avoid; 233 | } 234 | } 235 | 236 | table.module_list { 237 | border-width: 1px; 238 | border-style: solid; 239 | border-color: #cccccc; 240 | border-collapse: collapse; 241 | } 242 | table.module_list td { 243 | border-width: 1px; 244 | padding: 3px; 245 | border-style: solid; 246 | border-color: #cccccc; 247 | } 248 | table.module_list td.name { background-color: #f0f0f0; min-width: 200px; } 249 | table.module_list td.summary { width: 100%; } 250 | 251 | 252 | table.function_list { 253 | border-width: 1px; 254 | border-style: solid; 255 | border-color: #cccccc; 256 | border-collapse: collapse; 257 | } 258 | table.function_list td { 259 | border-width: 1px; 260 | padding: 3px; 261 | border-style: solid; 262 | border-color: #cccccc; 263 | } 264 | table.function_list td.name { background-color: #f0f0f0; min-width: 200px; } 265 | table.function_list td.summary { width: 100%; } 266 | 267 | ul.nowrap { 268 | overflow:auto; 269 | white-space:nowrap; 270 | } 271 | 272 | dl.table dt, dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;} 273 | dl.table dd, dl.function dd {padding-bottom: 1em; margin: 10px 0 0 20px;} 274 | dl.table h3, dl.function h3 {font-size: .95em;} 275 | 276 | /* stop sublists from having initial vertical space */ 277 | ul ul { margin-top: 0px; } 278 | ol ul { margin-top: 0px; } 279 | ol ol { margin-top: 0px; } 280 | ul ol { margin-top: 0px; } 281 | 282 | /* make the target distinct; helps when we're navigating to a function */ 283 | a:target + * { 284 | background-color: #FF9; 285 | } 286 | 287 | 288 | /* styles for prettification of source */ 289 | pre .comment { color: #558817; } 290 | pre .constant { color: #a8660d; } 291 | pre .escape { color: #844631; } 292 | pre .keyword { color: #aa5050; font-weight: bold; } 293 | pre .library { color: #0e7c6b; } 294 | pre .marker { color: #512b1e; background: #fedc56; font-weight: bold; } 295 | pre .string { color: #8080ff; } 296 | pre .number { color: #f8660d; } 297 | pre .function-name { color: #60447f; } 298 | pre .operator { color: #2239a8; font-weight: bold; } 299 | pre .preprocessor, pre .prepro { color: #a33243; } 300 | pre .global { color: #800080; } 301 | pre .user-keyword { color: #800080; } 302 | pre .prompt { color: #558817; } 303 | pre .url { color: #272fc2; text-decoration: underline; } 304 | 305 | -------------------------------------------------------------------------------- /examples/bench.lua: -------------------------------------------------------------------------------- 1 | -- Perform some benchmarks to compare bint and lua number speed 2 | 3 | local bint = require 'bint'(256) 4 | local os_clock = os.clock 5 | 6 | local function bench(n, name, f, a, b) 7 | -- warmup 8 | for _=1,n/100 do 9 | assert(f(a, b) ~= nil) 10 | end 11 | local start = os_clock() 12 | for _=1,n do 13 | assert(f(a, b) ~= nil) 14 | end 15 | local elapsed = (os_clock() - start) * 1000 16 | print(string.format('%s %10.02fms', name, elapsed)) 17 | return elapsed 18 | end 19 | 20 | local function bench2(n, name, f, a, b) 21 | local tluan = bench(n, string.format('luan %8s', name), f, a, b) 22 | local tbint = bench(n, string.format('bint %8s', name), f, bint.tobint(a), bint.tobint(b)) 23 | local factor = tbint/tluan 24 | print(string.format('fact %8s %10.02fx', name, factor)) 25 | end 26 | 27 | bench2(100000, 'add', function(a, b) return a + b end, 1, 2) 28 | bench2(100000, 'sub', function(a, b) return a - b end, 1, 2) 29 | bench2(100000, 'mul', function(a, b) return a * b end, 1, 2) 30 | bench2(30000, 'idiv', function(a, b) return a // b end, 1, 2) 31 | bench2(30000, 'mod', function(a, b) return a % b end, 1, 2) 32 | bench2(30000, 'div', function(a, b) return a / b end, 1, 2) 33 | bench2(100000, 'shl', function(a, b) return a << b end, 1, 2) 34 | bench2(100000, 'shr', function(a, b) return a >> b end, 1, 2) 35 | bench2(100000, 'band', function(a, b) return a & b end, 1, 2) 36 | bench2(100000, 'bor', function(a, b) return a | b end, 1, 2) 37 | bench2(100000, 'bxor', function(a, b) return a ~ b end, 1, 2) 38 | bench2(100000, 'bnot', function(a) return ~a end, 1) 39 | bench2(100000, 'unm', function(a) return -a end, 1) 40 | bench2(100000, 'eq', function(a, b) return a == b end, 1, 2) 41 | bench2(100000, 'lt', function(a, b) return a < b end, 1, 2) 42 | bench2(100000, 'le', function(a, b) return a <= b end, 1, 2) 43 | bench2(30000, 'pow', function(a, b) return a ^ b end, 1, 2) 44 | 45 | bench(100000, 'bint abs', function(a) return bint.abs(a) end, 1) 46 | bench(100000, 'bint dec', function(a) return bint.dec(a) end, 1) 47 | bench(100000, 'bint inc', function(a) return bint.inc(a) end, 1) 48 | bench(30000, 'bint ult', function(a, b) return bint.ult(a, b) end, 1, 2) 49 | bench(30000, 'bint ule', function(a, b) return bint.ule(a, b) end, 1, 2) 50 | bench(30000, 'bint ipow', function(a, b) return bint.ipow(a, b) end, 1, 2) 51 | 52 | bench(30000, 'luab tonumber', function(a) return tonumber(a) end, '2147483648') 53 | bench(30000, 'bint frombase', function(a) return bint.frombase(a) end, '2147483648') 54 | bench2(30000, 'tostring', function(a) return tostring(a) end, 1) 55 | -------------------------------------------------------------------------------- /examples/e.lua: -------------------------------------------------------------------------------- 1 | -- Compute the first 100 digits of Euler's number 2 | -- See https://en.wikipedia.org/wiki/E_(mathematical_constant) 3 | 4 | local bint = require 'bint'(512) 5 | 6 | local digits = 100 7 | local e = bint.zero() 8 | local one = bint.ipow(10, digits+10) 9 | local factorial = bint.one() 10 | for i=0,digits+10 do 11 | e = e + (one // factorial) 12 | factorial = factorial * (i+1) 13 | end 14 | e = tostring(e) 15 | e = e:sub(1,1) .. '.' .. e:sub(2, digits+1) 16 | print(e) 17 | assert(e == '2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274') 18 | -------------------------------------------------------------------------------- /examples/factorial.lua: -------------------------------------------------------------------------------- 1 | -- Compute the factorial of 100 2 | -- See https://en.wikipedia.org/wiki/Factorial 3 | 4 | local bint = require 'bint'(576) 5 | 6 | local function factorial(n) 7 | if n <= 0 then 8 | return 1 9 | else 10 | return n * factorial(n-1) 11 | end 12 | end 13 | 14 | local x = factorial(bint(100)) 15 | print('The factorial of 100 is:') 16 | print(x) 17 | 18 | assert(tostring(x) == '\z 19 | 933262154439441526816992388562667004907159682643816214685929638952175999932299\z 20 | 15608941463976156518286253697920827223758251185210916864000000000000000000000000') 21 | -------------------------------------------------------------------------------- /examples/fibonacci.lua: -------------------------------------------------------------------------------- 1 | -- Compute the 1000th Fibonacci number 2 | -- See https://en.wikipedia.org/wiki/Fibonacci_number 3 | 4 | local bint = require 'bint'(768) 5 | 6 | local function fibonacci(n) 7 | local first, second = bint.zero(), bint.one() 8 | for _=0,n-1 do 9 | first, second = second, first 10 | second = second + first 11 | end 12 | return first 13 | end 14 | 15 | local x = fibonacci(1001) 16 | print('The 1000th fibonnaci number is:') 17 | print(x) 18 | 19 | assert(tostring(x) == '\z 20 | 703303677114228158218352548771835497701812698363587327426049050871545371181969\z 21 | 335797422494945626117334877504492417659910881863632654502236471060120533741212\z 22 | 73867339111198139373125598767690091902245245323403501') -------------------------------------------------------------------------------- /examples/pi.lua: -------------------------------------------------------------------------------- 1 | -- Compute the first 100 digits on pi using the Machin-like formula 2 | -- See https://en.wikipedia.org/wiki/Machin-like_formula 3 | 4 | local bint = require 'bint'(512) 5 | 6 | local function arctan_denom(x, ndigits) 7 | local sum = bint.zero() 8 | local one = bint.ipow(10, ndigits) 9 | local d = bint.new(x) 10 | local d2 = -(d*d) 11 | local i = 0 12 | repeat 13 | local term = one // (d * (2*i + 1)) 14 | sum = sum + term 15 | d = d * d2 16 | i = i + 1 17 | until term:iszero() 18 | return sum 19 | end 20 | 21 | local function compute_pi(ndigits) 22 | local ndigits2 = ndigits + 10 23 | local pi = 4*(4*arctan_denom(5, ndigits2) - arctan_denom(239, ndigits2)) 24 | pi = tostring(pi) 25 | pi = pi:sub(1,1) .. '.' .. pi:sub(2, ndigits + 1) 26 | return pi 27 | end 28 | 29 | local pi = compute_pi(100) 30 | print('The first 100 pi digits are:') 31 | print(pi) 32 | assert(pi == '3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679') 33 | -------------------------------------------------------------------------------- /examples/rsa.lua: -------------------------------------------------------------------------------- 1 | -- Simple RSA cryptosystem example 2 | -- See https://en.wikipedia.org/wiki/RSA_(cryptosystem) 3 | 4 | local bint = require 'bint'(512) 5 | 6 | local function gcd(a, b) 7 | while not bint.iszero(b) do 8 | a, b = b, bint.umod(a, b) 9 | end 10 | return a 11 | end 12 | 13 | local function lcm(a, b) 14 | return bint.abs(a * b) // gcd(a, b) 15 | end 16 | 17 | -- Returns modular multiplicative inverse m s.t. (a * m) % m == 1 18 | local function modinv(a, m) 19 | local r, inv, s = bint(m), bint.one(), bint.zero() 20 | while not r:iszero() do 21 | local quo, rem = bint.idivmod(a, r) 22 | s, r, inv, a = inv - quo * s, rem, s, r 23 | end 24 | assert(a:isone(), 'no inverse') 25 | return inv % m 26 | end 27 | 28 | -- 1. Choose two distinct primes 29 | local p = bint('5011956100955230700919988831') 30 | local q = bint('5989833698158308593254005067') 31 | print('p = ' .. tostring(p)) 32 | print('q = ' .. tostring(q)) 33 | 34 | -- 2. Compute n = p * q 35 | local n = p * q 36 | print('n = ' .. tostring(n)) 37 | assert(n == bint('30020783547191766561527759475184666413598963507657406677')) 38 | 39 | -- 3. Compute the totient 40 | local phi_n = lcm(p - 1, q - 1) 41 | print('phi_n = ' .. tostring(phi_n)) 42 | assert(phi_n == bint('5003463924531961093587959910697146102414237368913902130')) 43 | 44 | -- 4. Choose any number e that 1 < e < phi_n and is coprime to phi_n 45 | local e = bint('65537') 46 | print('e = ' .. tostring(e)) 47 | 48 | -- 5. Compute d, the modular multiplicative inverse 49 | local d = modinv(e, phi_n) 50 | print('d = ' .. tostring(d)) 51 | assert(d == bint('2768292749187922993934715143535384861582621221551460873')) 52 | 53 | -- The public key is (n, e), implement the encrypt function 54 | local function encrypt(msg) 55 | return bint.upowmod(msg, e, n) 56 | end 57 | 58 | -- The private key is (n, d), implement the decrypt function 59 | local function decrypt(msg) 60 | return bint.upowmod(msg, d, n) 61 | end 62 | 63 | -- Test encrypt and decrypt 64 | print('Message encryption test:') 65 | local msg = 'Hello world!' 66 | print('Message: '..msg) 67 | local x = bint.frombe(msg) 68 | assert(x < n) 69 | print('x = 0x' .. bint.tobase(x, 16)) 70 | local c = encrypt(x) 71 | print('c = 0x' .. bint.tobase(c, 16)) 72 | assert(c == bint.frombase('81fa941a0bf7a387f0ad060b90a5cd251be4031b4df39a', 16)) 73 | local m = decrypt(c) 74 | print('m = 0x' .. bint.tobase(m, 16)) 75 | assert(m == x) 76 | local decoded = bint.tobe(m, true) 77 | print('Decoded: '..decoded) 78 | assert(decoded == msg) 79 | print('success!') 80 | -------------------------------------------------------------------------------- /examples/secp256k1.lua: -------------------------------------------------------------------------------- 1 | -- Simple Elliptic Curve Cryptography of secp256k1 for encrypting/decrypting/signing messages 2 | -- See https://en.bitcoin.it/wiki/Secp256k1 3 | 4 | local bint = require 'bint'(768) 5 | 6 | -- Returns modular multiplicative inverse m s.t. (a * m) % m == 1 7 | local function modinv(a, m) 8 | local r, inv, s = bint(m), bint.one(), bint.zero() 9 | while not r:iszero() do 10 | local quo, rem = bint.idivmod(a, r) 11 | s, r, inv, a = inv - quo * s, rem, s, r 12 | end 13 | assert(a:isone(), 'no inverse') 14 | return inv % m 15 | end 16 | 17 | -- Curve prime number 18 | local P = bint('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f') 19 | 20 | -- Curve order 21 | local N = bint('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141') 22 | 23 | -- Curve parameters 24 | local A = bint(0) 25 | local B = bint(7) 26 | 27 | -- Curve point class 28 | local CurvePoint = setmetatable({_secp256k1 = true}, {__call = function(mt, a) return setmetatable(a, mt) end}) 29 | CurvePoint.__index = CurvePoint 30 | 31 | -- Curve point at infinity 32 | local O = CurvePoint{x=bint.zero(), y=math.huge} 33 | 34 | -- Curve generator point 35 | local G = CurvePoint{ 36 | x = bint('0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), 37 | y = bint('0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8'), 38 | } 39 | 40 | -- Checks if points in the curve are equal. 41 | function CurvePoint.__eq(a, b) 42 | return a.x == b.x and bint.eq(b.y, b.y) 43 | end 44 | 45 | -- Convert a curve point to a string. 46 | function CurvePoint:__tostring() 47 | return string.format("{x=%s, y=%s}", self.x, self.y) 48 | end 49 | 50 | -- Add two points in the curve 51 | function CurvePoint.__add(a, b) 52 | assert(a._secp256k1 and b._secp256k1, 'invalid params') 53 | -- handle special case of P + O = O + P = O 54 | if a == O then return b end 55 | if b == O then return a end 56 | -- handle special case of P + (-P) = O 57 | if a.x == b.x and a.y ~= b.y then return O end 58 | -- compute the "slope" 59 | local m 60 | if a.x == b.x then -- (a.y = b.y is guaranteed too per above check) 61 | m = ((3 * a.x:upowmod(2, P) + A) * modinv(2 * a.y, P) % P) 62 | else 63 | m = ((a.y - b.y) * modinv(a.x - b.x, P) % P) 64 | end 65 | -- compute the new point 66 | local x = (m*m - a.x - b.x) % P 67 | local y = (-(m*(x - a.x) + a.y)) % P 68 | return CurvePoint{x=x, y=y} 69 | end 70 | 71 | -- Multiply point p by scalar n. 72 | function CurvePoint.__mul(p, n) 73 | n = bint(n) 74 | assert(n:ispos() and p._secp256k1, 'invalid params') 75 | local res = O 76 | local acc = p 77 | while n:ispos() do 78 | if n:isodd() then 79 | res = res + acc 80 | end 81 | n:_shrone() 82 | acc = acc + acc 83 | end 84 | return res 85 | end 86 | 87 | -- Checks if a point is on the curve, meaning if y^2 = x^3 + 7 holds true. 88 | function CurvePoint:valid() 89 | if self == O then return true end 90 | local rem = (self.y:upowmod(2, P) - self.x:upowmod(3, P) - 7) % P 91 | return rem:iszero() 92 | end 93 | 94 | 95 | do -- Tests some curve operations 96 | assert(G:valid()) 97 | assert(O:valid()) 98 | assert((G+G):valid()) 99 | assert(((G+G)+G):valid()) 100 | assert((G+(G+G)):valid()) 101 | assert((O+G):valid()) 102 | assert((G+O):valid()) 103 | assert((G*1):valid()) 104 | assert((G*2):valid()) 105 | assert((G*3):valid()) 106 | assert(G*2 == G+G) 107 | assert(G*3 == G+G+G) 108 | end 109 | 110 | do -- Test encrypt and decrypt 111 | -- Very simple XOR crypt (very insecure, but works for demo purposes, use a better cipher like AES!) 112 | local function xorcrypt(msg, symmetric_private_key) 113 | local xor_key = symmetric_private_key.x ~ symmetric_private_key.y 114 | return msg ~ xor_key 115 | end 116 | 117 | -- Encrypt message using a private symmetric key and the curve public key. 118 | local function encrypt(msg, symmetric_private_key, public_key) 119 | return xorcrypt(msg, public_key * symmetric_private_key) 120 | end 121 | 122 | -- Decrypt message using a public symmetric key and the curve private key. 123 | local function decrypt(msg, symmetric_public_key, private_key) 124 | return xorcrypt(msg, symmetric_public_key * private_key) 125 | end 126 | 127 | print 'Message encryption test:' 128 | 129 | -- Choose a private key 130 | local private_key = bint.frombe('This is my private key, hide it!') 131 | print('private_key = ' .. tostring(private_key)) 132 | 133 | -- Compute public key 134 | local public_key = G * private_key 135 | print('public_key = ' .. tostring(public_key)) 136 | assert(public_key:valid()) 137 | 138 | -- Generate a random scalar (ideally should be a random number) 139 | local symmetric_private_key = bint.frombe('Symmetric key random, hide it!') 140 | local symmetric_public_key = G * symmetric_private_key 141 | assert(symmetric_public_key:valid()) 142 | 143 | local message = bint.frombe('Hello world!') 144 | local encrypted_message = encrypt(message, symmetric_private_key, public_key) 145 | print('Message: ' .. message:tobe(true)) 146 | print('encrypted_message = 0x' .. encrypted_message:tobase(16)) 147 | 148 | local decrypted_message = decrypt(encrypted_message, symmetric_public_key, private_key) 149 | print('Decoded: ' .. decrypted_message:tobe(true)) 150 | assert(message == decrypted_message) 151 | end 152 | 153 | do -- Test message signature using EdDSA (see https://en.wikipedia.org/wiki/EdDSA) 154 | print('Message signature test:') 155 | 156 | -- Simple hash for demo purposes (not very secure, use a better hash like SHA-256!) 157 | local function hash(msg, sign_public_key, public_key) 158 | local function h(v) return (v << 13) ~ (v >> 17) ~ (v << 5) end 159 | local s = bint.zero() 160 | local k = bint('0x9ddfea08eb382d69') 161 | s = (h(msg) ~ s) * k; s = s ~ (s >> 47) 162 | s = (h(sign_public_key.x) ~ s) * k; s = s ~ (s >> 47) 163 | s = (h(sign_public_key.y) ~ s) * k; s = s ~ (s >> 47) 164 | s = (h(public_key.x) ~ s) * k; s = s ~ (s >> 47) 165 | s = (h(public_key.y) ~ s) * k; s = s ~ (s >> 47) 166 | return s % bint.ipow(2, 256) 167 | end 168 | 169 | -- Signs a message using private keys 170 | local function sign(message, sign_private_key, private_key) 171 | local sign_public_key = G * sign_private_key 172 | local public_key = G * private_key 173 | local message_hash = hash(message, sign_public_key, public_key) 174 | local sign_binding_factor = (sign_private_key + private_key * message_hash) % N 175 | return sign_public_key, sign_binding_factor 176 | end 177 | 178 | -- Verifies a message using public signature and public keys. 179 | local function verify(message, sign_binding_factor, sign_public_key, public_key) 180 | local message_hash = hash(message, sign_public_key, public_key) 181 | return sign_public_key + public_key * message_hash == G * sign_binding_factor 182 | end 183 | 184 | -- Choose a private key 185 | local private_key = bint.frombe('This is my private key, hide it!') 186 | print('private_key = ' .. tostring(private_key)) 187 | 188 | -- Compute public key 189 | local public_key = G * private_key 190 | print('public_key = ' .. tostring(public_key)) 191 | assert(public_key:valid()) 192 | 193 | -- Generate a random scalar (ideally should be a random number) 194 | local sign_private_key = bint.frombe('Signature random, hide it!') 195 | 196 | local message = bint.frombe("Hello world!") 197 | print('Message: '.. message:tobe(true)) 198 | 199 | -- Sign message 200 | local sign_public_key, sign_binding_factor = sign(message, sign_private_key, private_key) 201 | print(string.format('signature = (%s, %s)', sign_public_key, sign_binding_factor)) 202 | assert(sign_public_key:valid()) 203 | 204 | -- Verify message 205 | local ok = verify(message, sign_binding_factor, sign_public_key, public_key) 206 | print('Verification: ' .. tostring(ok)) 207 | assert(ok == true) 208 | end 209 | 210 | print('success!') 211 | -------------------------------------------------------------------------------- /examples/simple.lua: -------------------------------------------------------------------------------- 1 | local bint = require 'bint'(256) -- use 256 bits integers 2 | local x = bint(1) 3 | x = x << 128 4 | print(x) -- outputs: 340282366920938463463374607431768211456 5 | assert(tostring(x) == '340282366920938463463374607431768211456') 6 | -------------------------------------------------------------------------------- /rockspecs/bint-0.5.2-1.rockspec: -------------------------------------------------------------------------------- 1 | package = "bint" 2 | version = "0.5.2-1" 3 | source = { 4 | url = "git://github.com/edubart/lua-bint.git", 5 | tag = "v0.5.2" 6 | } 7 | description = { 8 | summary = "Arbitrary precision integer arithmetic library in pure Lua", 9 | detailed = [[Small portable arbitrary-precision integer arithmetic library in pure Lua for 10 | computing with large integers. 11 | ]], 12 | homepage = "https://github.com/edubart/lua-bint", 13 | license = "MIT" 14 | } 15 | dependencies = { 16 | "lua >= 5.3", 17 | } 18 | build = { 19 | type = "builtin", 20 | modules = { 21 | ['bint'] = 'bint.lua', 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /rockspecs/bint-dev-1.rockspec: -------------------------------------------------------------------------------- 1 | package = "bint" 2 | version = "dev-1" 3 | source = { 4 | url = "git://github.com/edubart/lua-bint.git", 5 | branch = "master" 6 | } 7 | description = { 8 | summary = "Arbitrary precision integer arithmetic library in pure Lua", 9 | detailed = [[Small portable arbitrary-precision integer arithmetic library in pure Lua for 10 | computing with large integers. 11 | ]], 12 | homepage = "https://github.com/edubart/lua-bint", 13 | license = "MIT" 14 | } 15 | dependencies = { 16 | "lua >= 5.3", 17 | } 18 | build = { 19 | type = "builtin", 20 | modules = { 21 | ['bint'] = 'bint.lua', 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests.lua: -------------------------------------------------------------------------------- 1 | local function luainteger_bitsize() 2 | local n, i = -1, 0 3 | repeat 4 | n, i = n >> 16, i + 16 5 | until n==0 6 | return i 7 | end 8 | 9 | local function test(bits, wordbits) 10 | local bint = require 'bint'(bits, wordbits) 11 | local luabits = luainteger_bitsize() 12 | local bytes = bits // 8 13 | 14 | local function assert_eq(a, b) 15 | if a ~= b then --luacov:disable 16 | local msg = string.format( 17 | "assertion failed:\n expected '%s' of type '%s',\n but got '%s' of type '%s'", 18 | b, type(b), a, type(a)) 19 | error(msg) 20 | end --luacov:enable 21 | end 22 | 23 | local function assert_eqf(a, b) 24 | assert(bint.abs(a - b) <= 1e-6, 'assertion failed') 25 | end 26 | 27 | do --utils 28 | assert(bint(-2):iszero() == false) 29 | assert(bint(-1):iszero() == false) 30 | assert(bint(0):iszero() == true) 31 | assert(bint(1):iszero() == false) 32 | assert(bint(2):iszero() == false) 33 | assert(bint.iszero(0) == true) 34 | 35 | assert(bint(-2):isone() == false) 36 | assert(bint(-1):isone() == false) 37 | assert(bint(0):isone() == false) 38 | assert(bint(1):isone() == true) 39 | assert(bint(2):isone() == false) 40 | assert(bint(1 | (1 << 31)):isone() == false) 41 | assert(bint.isone(1) == true) 42 | 43 | assert(bint(-1):isminusone() == true) 44 | assert(bint(-2):isminusone() == false) 45 | assert(bint(1):isminusone() == false) 46 | assert(bint(0):isminusone() == false) 47 | assert(bint(2):isminusone() == false) 48 | assert(bint.isminusone(-1) == true) 49 | 50 | assert(bint(-1):isneg() == true) 51 | assert(bint(-2):isneg() == true) 52 | assert(bint(0):isneg() == false) 53 | assert(bint(1):isneg() == false) 54 | assert(bint(2):isneg() == false) 55 | assert(bint.isneg(-1) == true) 56 | 57 | assert(bint(-1):ispos() == false) 58 | assert(bint(-2):ispos() == false) 59 | assert(bint(0):ispos() == false) 60 | assert(bint(1):ispos() == true) 61 | assert(bint(2):ispos() == true) 62 | assert(bint.ispos(1) == true) 63 | 64 | assert(bint(-2):iseven() == true) 65 | assert(bint(-1):iseven() == false) 66 | assert(bint(0):iseven() == true) 67 | assert(bint(1):iseven() == false) 68 | assert(bint(2):iseven() == true) 69 | assert(bint(3):iseven() == false) 70 | assert(bint.iseven(2) == true) 71 | assert(bint.iseven(-2) == true) 72 | 73 | assert(bint(-2):isodd() == false) 74 | assert(bint(-1):isodd() == true) 75 | assert(bint(0):isodd() == false) 76 | assert(bint(1):isodd() == true) 77 | assert(bint(2):isodd() == false) 78 | assert(bint(3):isodd() == true) 79 | assert(bint.isodd(1) == true) 80 | assert(bint.isodd(-1) == true) 81 | 82 | assert(bint.eq(1, 1) == true) 83 | assert(bint.eq(1, 0) == false) 84 | assert(bint.eq(1.5, 1.5) == true) 85 | assert(bint.eq(1.5, 1) == false) 86 | assert(bint.eq(1.5, 2.5) == false) 87 | 88 | assert(bint(1) < 1.5 == true) 89 | assert(bint(1) <= 1.5 == true) 90 | assert(bint(1) <= 1e20 == true) 91 | 92 | assert(bint.isbint(1) == false) 93 | assert(bint.isbint(bint(1)) == true) 94 | assert(bint.isintegral(1) == true) 95 | assert(bint.isintegral(bint(1)) == true) 96 | assert(bint.isnumeric(1) == true) 97 | assert(bint.isnumeric(1.5) == true) 98 | assert(bint.isnumeric(bint(1)) == true) 99 | assert(bint.type(1) == 'integer') 100 | assert(bint.type(1.5) == 'float') 101 | assert(bint.type(bint(1)) == 'bint') 102 | 103 | assert(tostring(bint.frombase('9223372036854775807')) == '9223372036854775807') 104 | assert(tostring(bint.frombase('-9223372036854775808')) == '-9223372036854775808') 105 | assert(bint.frombase('AAAAAAAAAAAAAAAAAAA') == nil) 106 | assert(bint.frombase('AAAAAAAAAAAAAAAAAAA_') == nil) 107 | 108 | assert(bint.fromstring(1) == nil) 109 | assert(bint.eq(bint.fromstring('0xff'), 0xff)) 110 | assert(bint.eq(bint.fromstring('+0xff'), 0xff)) 111 | assert(bint.eq(bint.fromstring('-0xff'), -0xff)) 112 | assert(bint.eq(bint.fromstring('0b10100'), 0x14)) 113 | assert(bint.eq(bint.fromstring('0b0'), 0)) 114 | assert(bint.eq(bint.fromstring('0b1'), 1)) 115 | assert(bint.eq(bint.fromstring('-0b1'), -1)) 116 | assert(bint.eq(bint.fromstring('+0b1'), 1)) 117 | assert(bint.eq(bint.fromstring('0'), 0)) 118 | assert(bint.eq(bint.fromstring('-1'), -1)) 119 | assert(bint.eq(bint.fromstring('1234'), 1234)) 120 | 121 | assert(bint.fromle('\x00') == bint.zero()) 122 | assert(bint.fromle('\x01') == bint.one()) 123 | assert(bint.fromle('\x01\x02\x03') == bint.frombase('030201', 16)) 124 | assert(bint.fromle(string.rep('\x00', bytes)) == bint.zero()) 125 | assert(bint.fromle(string.rep('\x01', bytes)) == bint.frombase(string.rep('01', bytes), 16)) 126 | assert(bint.fromle(string.rep('\x01', bytes+32)) == bint.frombase(string.rep('01', bytes), 16)) 127 | assert(bint.fromle(string.rep('\xff', bytes)) == bint.frombase(string.rep('ff', bytes), 16)) 128 | assert(bint.fromle(string.rep('\xff', bytes+32)) == bint.frombase(string.rep('ff', bytes), 16)) 129 | 130 | assert(bint.frombe('\x00') == bint.zero()) 131 | assert(bint.frombe('\x01') == bint.one()) 132 | assert(bint.frombe('\x03\x02\x01') == bint.frombase('030201', 16)) 133 | assert(bint.frombe(string.rep('\x00', bytes)) == bint.zero()) 134 | assert(bint.frombe(string.rep('\x01', bytes)) == bint.frombase(string.rep('01', bytes), 16)) 135 | assert(bint.frombe(string.rep('\x01', bytes+32)) == bint.frombase(string.rep('01', bytes), 16)) 136 | assert(bint.frombe(string.rep('\xff', bytes)) == bint.frombase(string.rep('ff', bytes), 16)) 137 | assert(bint.frombe(string.rep('\xff', bytes+32)) == bint.frombase(string.rep('ff', bytes), 16)) 138 | 139 | if bits == 160 then 140 | local x = bint.new('0x4340ac4FcdFC5eF8d34930C96BBac2Af1301DF40') 141 | local x_be = '\x43\x40\xac\x4F\xcd\xFC\x5e\xF8\xd3\x49\x30\xC9\x6B\xBa\xc2\xAf\x13\x01\xDF\x40' 142 | assert(bint.frombe(bint.tobe(x)) == x) 143 | assert(bint.fromle(bint.tole(x)) == x) 144 | assert(bint.tobe(bint.frombe(x_be)) == x_be) 145 | assert(bint.tole(bint.fromle(x_be:reverse())) == x_be:reverse()) 146 | end 147 | 148 | assert(bint.tole(0) == string.rep('\x00', bytes)) 149 | assert(bint.tole(0, true) == '\x00') 150 | assert(bint.tole(1) == '\x01'..string.rep('\x00', bytes-1)) 151 | assert(bint.tole(1, true) == '\x01') 152 | assert(bint.tole(0x010203) == '\x03\x02\x01'..string.rep('\x00', bytes-3)) 153 | assert(bint.tole(0x010203, true) == '\x03\x02\x01') 154 | assert(bint.tole(-1) == string.rep('\xff', bytes)) 155 | assert(bint.tole(-1, true) == string.rep('\xff', bytes)) 156 | 157 | assert(bint.tobe(0) == string.rep('\x00', bytes)) 158 | assert(bint.tobe(0, true) == '\x00') 159 | assert(bint.tobe(1) == string.rep('\x00', bytes-1)..'\x01') 160 | assert(bint.tobe(1, true) == '\x01') 161 | assert(bint.tobe(0x010203) == string.rep('\x00', bytes-3)..'\x01\x02\x03') 162 | assert(bint.tobe(0x010203, true) == '\x01\x02\x03') 163 | assert(bint.tobe(-1) == string.rep('\xff', bytes)) 164 | assert(bint.tobe(-1, true) == string.rep('\xff', bytes)) 165 | 166 | assert((bint.maxinteger() + 1) == bint.mininteger()) 167 | assert((bint.mininteger() - 1) == bint.maxinteger()) 168 | 169 | assert(bint.max(bint(1), bint(2)) == bint(2)) 170 | assert(bint.max(bint(1), 2) == bint(2)) 171 | assert(bint.max(bint(1), 2.5) == 2.5) 172 | assert(bint.max(1.5, bint(2)) == bint(2)) 173 | 174 | assert(bint.min(bint(3), bint(2)) == bint(2)) 175 | assert(bint.min(bint(3), 2) == bint(2)) 176 | assert(bint.min(bint(3), 2.5) == 2.5) 177 | assert(bint.min(3.5, bint(2)) == bint(2)) 178 | 179 | if bits > 96 then 180 | assert((bint(1) << 96):tonumber() > 1e28) 181 | assert((-(bint(1) << 96)):tonumber() < -1e28) 182 | end 183 | end 184 | 185 | do -- number conversion 186 | local function test_num2num(x) 187 | assert_eq(bint(x):tointeger(), x) 188 | assert_eq(bint.new(x):tointeger(), x) 189 | assert_eq(bint.tobint(x):tointeger(), x) 190 | assert_eq(bint.fromuinteger(x):tointeger(), x) 191 | assert_eq(bint.new(bint(x)):tointeger(), x) 192 | assert_eq(bint.tobint(bint(x)):tointeger(), x) 193 | assert_eq(bint.new(tostring(x)):tointeger(), x) 194 | assert_eq(bint.tobint(tostring(x)):tointeger(), x) 195 | assert_eq(bint.tointeger(x), x) 196 | assert_eq(bint.tointeger(bint(x)), x) 197 | assert_eq(bint.tointeger(x), x) 198 | assert_eq(bint.tointeger(x * 1.0), x) 199 | assert_eq(bint.tointeger(bint(x)), x) 200 | assert_eq(bint.zero():_assign(x):tointeger(), x) 201 | end 202 | local function test_num2hex(x) 203 | assert_eq(bint(x):tobase(16), ('%x'):format(x)) 204 | end 205 | local function test_num2dec(x) 206 | assert_eq(tostring(bint(x)), ('%d'):format(x)) 207 | end 208 | local function test_num2oct(x) 209 | assert_eq(bint(x):tobase(8), ('%o'):format(x)) 210 | end 211 | local function test_str2num(x) 212 | assert_eq(bint.frombase(tostring(x)):tointeger(), x) 213 | end 214 | local function test_ops(x) 215 | test_num2num(x) 216 | test_num2num(-x) 217 | test_num2hex(x) 218 | test_num2oct(x) 219 | if bits == luabits then 220 | test_num2hex(-x) 221 | test_num2oct(-x) 222 | end 223 | test_num2dec(x) 224 | test_num2dec(-x) 225 | test_str2num(x) 226 | test_str2num(-x) 227 | end 228 | assert_eq(bint.frominteger(nil), nil) 229 | assert_eq(bint.fromuinteger(nil), nil) 230 | 231 | assert_eq(bint.frombase(nil), nil) 232 | assert_eq(bint.frombase('ff', 10), nil) 233 | assert_eq(bint.frombase('x', 37), nil) 234 | assert_eq(bint.frombase('', 10), nil) 235 | 236 | assert_eq(bint.trunc(nil), nil) 237 | assert_eq(bint.trunc(1.5):tointeger(), 1) 238 | assert_eq(bint.trunc(-1.5):tointeger(), -1) 239 | assert_eq(bint.trunc(bint(1)), bint(1)) 240 | 241 | assert_eq(bint.tonumber(1), 1) 242 | assert_eq(bint.tonumber(bint(1)), 1) 243 | 244 | assert_eq(bint.tointeger(1.0/0.0), nil) 245 | assert_eq(bint.tointeger(-1.0/0.0), nil) 246 | assert_eq(bint.tointeger(0.0/0.0), nil) 247 | assert_eq(bint.tointeger(1.5), nil) 248 | assert_eq(bint.tointeger(1), 1) 249 | assert_eq(bint.tointeger(bint(1)), 1) 250 | assert_eq(bint.tointeger(bint(math.mininteger)), math.mininteger) 251 | assert_eq(bint.tointeger(bint(math.maxinteger)), math.maxinteger) 252 | 253 | assert_eq(bint.touinteger(1.5), nil) 254 | assert_eq(bint.touinteger(1), 1) 255 | assert_eq(bint.touinteger(bint(1)), 1) 256 | 257 | assert_eq(bint.tobint(nil), nil) 258 | assert_eq(bint.tobint(1), bint(1)) 259 | assert_eq(bint.tobint(1.5), nil) 260 | 261 | assert_eq(bint.parse(1), bint(1)) 262 | assert_eq(bint.parse(1.5), 1.5) 263 | 264 | assert_eq(bint.tobase(math.mininteger, 10), tostring(math.mininteger)) 265 | assert_eq(bint.tobase(math.maxinteger, 10), tostring(math.maxinteger)) 266 | assert_eq(bint.tobase(1, 10), '1') 267 | assert_eq(bint.tobase(8, 7), '11') 268 | assert_eq(bint.tobase(1, 37), nil) 269 | assert_eq(bint.tobase(1.5, 10), nil) 270 | assert_eq(bint.tobase(0xff, 16, true), 'ff') 271 | assert_eq(bint.tobase(-0xff, 16, false), '-ff') 272 | if bits == 64 then 273 | assert_eq(bint.tobase(-1, 16, true), 'ffffffffffffffff') 274 | assert_eq(bint.tobase(-2, 16, true), 'fffffffffffffffe') 275 | elseif bits == 128 then 276 | assert_eq(bint.tobase('-1', 16, true), ('f'):rep(32)) 277 | end 278 | 279 | test_ops(0) 280 | test_ops(1) 281 | if luabits >= 64 then 282 | test_ops(0xfffffffffe) 283 | test_ops(0x123456789abc) 284 | end 285 | test_ops(0xfffffff) 286 | test_ops(0xfffffff) 287 | test_ops(0xf505c2) 288 | test_ops(0x9f735a) 289 | test_ops(0xcf7810) 290 | test_ops(0xbbc55f) 291 | end 292 | 293 | do -- add/sub/mul/band/bor/bxor/eq/lt/le 294 | local function test_add(x, y) 295 | assert_eq((bint(x) + bint(y)):tointeger(), x + y) 296 | assert_eq((bint(x):_add(y)):tointeger(), x + y) 297 | assert_eq(bint(x) + (y+0.5), x + (y+0.5)) 298 | end 299 | local function test_sub(x, y) 300 | assert_eq((bint(x) - bint(y)):tointeger(), x - y) 301 | assert_eq((bint(x):_sub(y)):tointeger(), x - y) 302 | assert_eq(bint(x) - (y+0.5), x - (y+0.5)) 303 | end 304 | local function test_mul(x, y) 305 | assert_eq((bint(x) * bint(y)):tointeger(), x * y) 306 | assert_eq(bint(x) * (y+0.5), x * (y+0.5)) 307 | end 308 | local function test_band(x, y) 309 | assert_eq((bint(x) & bint(y)):tointeger(), x & y) 310 | end 311 | local function test_bor(x, y) 312 | assert_eq((bint(x) | bint(y)):tointeger(), x | y) 313 | end 314 | local function test_bxor(x, y) 315 | assert_eq((bint(x) ~ bint(y)):tointeger(), x ~ y) 316 | end 317 | local function test_eq(x, y) 318 | assert_eq(bint(x) == bint(y), x == y) 319 | end 320 | local function test_lt(x, y) 321 | assert_eq(bint(x) < bint(y), x < y) 322 | end 323 | local function test_ult(x, y) 324 | assert_eq(bint.ult(bint(x), bint(y)), math.ult(x, y)) 325 | end 326 | local function test_le(x, y) 327 | assert_eq(bint(x) <= bint(y), x <= y) 328 | end 329 | local function test_ule(x, y) 330 | assert_eq(bint.ule(bint(x), bint(y)), x == y or math.ult(x, y)) 331 | end 332 | local function test_ops2(x, y) 333 | test_add(x, y) 334 | test_sub(x, y) test_sub(y, x) 335 | test_mul(x, y) test_mul(y, x) 336 | test_band(x, y) 337 | test_bor(x, y) 338 | test_bxor(x, y) 339 | test_eq(x, y) test_eq(y, x) test_eq(x, x) test_eq(y, y) 340 | test_lt(x, y) test_lt(y, x) test_lt(x, x) test_lt(y, y) 341 | test_ult(x, y) test_ult(y, x) test_ult(x, x) test_ult(y, y) 342 | test_le(x, y) test_le(y, x) test_le(x, x) test_le(y, y) 343 | test_ule(x, y) test_ule(y, x) test_ule(x, x) test_ule(y, y) 344 | end 345 | local function test_ops(x, y) 346 | test_ops2(x, y) 347 | test_ops2(-x, y) 348 | test_ops2(-x, -y) 349 | test_ops2(x, -y) 350 | end 351 | test_ops(0, 0) 352 | test_ops(1, 1) 353 | test_ops(1, 2) 354 | test_ops(80, 20) 355 | test_ops(18, 22) 356 | test_ops(12, 8) 357 | test_ops(100080, 20) 358 | test_ops(18, 559022) 359 | test_ops(2000000000, 2000000000) 360 | test_ops(0x00ffff, 1) 361 | test_ops(0x00ffff00, 0x00000100) 362 | test_ops(1000001, 1000000) 363 | test_ops(42, 0) 364 | test_ops(101, 100) 365 | test_ops(242, 42) 366 | test_ops(1042, 0) 367 | test_ops(101010101, 101010100) 368 | test_ops(0x010000, 1) 369 | test_ops(0xf505c2, 0x0fffe0) 370 | test_ops(0x9f735a, 0x65ffb5) 371 | test_ops(0xcf7810, 0x04ff34) 372 | test_ops(0xbbc55f, 0x4eff76) 373 | test_ops(0x100000, 1) 374 | test_ops(0x010000, 1) 375 | test_ops(0xb5beb4, 0x01ffc4) 376 | test_ops(0x707655, 0x50ffa8) 377 | test_ops(0xf0a990, 0x1cffd1) 378 | test_ops(0x010203, 0x1020) 379 | test_ops(42, 0) 380 | test_ops(42, 1) 381 | test_ops(42, 2) 382 | test_ops(42, 10) 383 | test_ops(42, 100) 384 | test_ops(420, 1000) 385 | test_ops(200, 8) 386 | test_ops(2, 256) 387 | test_ops(500, 2) 388 | test_ops(500000, 2) 389 | test_ops(500, 500) 390 | test_ops(1000000000, 2) 391 | test_ops(2, 1000000000) 392 | test_ops(1000000000, 4) 393 | test_ops(0xfffffffe, 0xffffffff) 394 | test_ops(0xffffffff, 0xffffffff) 395 | test_ops(0xffffffff, 0x10000) 396 | test_ops(0xffffffff, 0x1000) 397 | test_ops(0xffffffff, 0x100) 398 | test_ops(0xffffffff, 1) 399 | test_ops(1000000, 1000) 400 | test_ops(1000000, 10000) 401 | test_ops(1000000, 100000) 402 | test_ops(1000000, 1000000) 403 | test_ops(1000000, 10000000) 404 | test_ops(0xffffffff, 0x005500aa) 405 | test_ops(7, 3) 406 | test_ops(0xffffffff, 0) 407 | test_ops(0, 0xffffffff) 408 | test_ops(0xffffffff, 0xffffffff) 409 | test_ops(0xffffffff, 0) 410 | test_ops(0, 0xffffffff) 411 | test_ops(0x00000000, 0xffffffff) 412 | test_ops(0x55555555, 0xaaaaaaaa) 413 | test_ops(0xffffffff, 0xffffffff) 414 | test_ops(4, 3) 415 | end 416 | 417 | do --shl/shr 418 | local function test_shl(x, y) 419 | assert_eq((bint(x) << y):tointeger(), x << y) 420 | end 421 | local function test_shr(x, y) 422 | assert_eq((bint(x) >> y):tointeger(), x >> y) 423 | end 424 | local function test_brol(x, y) 425 | assert_eq(bint(x):brol(y):tointeger(), (x << y) | (x >> (64 - y))) 426 | end 427 | local function test_bror(x, y) 428 | assert_eq(bint(x):bror(y):tointeger(), (x >> y) | (x << (64 - y))) 429 | end 430 | local function test_shlone(x) 431 | assert_eq(bint(x):_shlone():tointeger(), x << 1) 432 | end 433 | local function test_shrone(x) 434 | assert_eq(bint(x):_shrone():tointeger(), x >> 1) 435 | end 436 | local function test_bwrap(x, y) 437 | assert_eq(bint.bwrap(x, y):tointeger(), x & ((1 << math.max(y, 0))-1)) 438 | end 439 | local function test_ops(x, y) 440 | test_shl(x, y) test_shl(x, -y) 441 | test_shr(x, y) test_shr(x, -y) 442 | test_bwrap(x, y) test_bwrap(x, -y) test_bwrap(-x, y) 443 | test_shlone(x) test_shlone(y) 444 | test_shrone(x) test_shrone(y) 445 | if bits == 64 then 446 | test_brol(x, y) 447 | test_bror(x, y) 448 | end 449 | end 450 | test_ops(math.maxinteger, 1) 451 | test_ops(math.maxinteger, math.maxinteger) 452 | if bits == 64 then 453 | test_ops(-1, 0) 454 | test_ops(-1, 1) 455 | test_ops(math.mininteger, 1) 456 | end 457 | test_ops(0, 0) 458 | test_ops(1, 0) 459 | test_ops(1, 1) 460 | test_ops(1, 2) 461 | test_ops(1, 3) 462 | test_ops(1, 4) 463 | test_ops(1, 5) 464 | test_ops(1, 6) 465 | test_ops(1, 7) 466 | test_ops(1, 8) 467 | test_ops(1, 9) 468 | test_ops(1, 10) 469 | test_ops(1, 11) 470 | test_ops(1, 12) 471 | test_ops(1, 13) 472 | test_ops(1, 14) 473 | test_ops(1, 15) 474 | test_ops(1, 16) 475 | test_ops(1, 17) 476 | test_ops(1, 18) 477 | test_ops(1, 19) 478 | test_ops(1, 20) 479 | test_ops(1, 64) 480 | test_ops(1, 100) 481 | test_ops(0xdd, 0x18) 482 | test_ops(0x68, 0x02) 483 | test_ops(0xf6, 1) 484 | test_ops(0x1a, 1) 485 | test_ops(0xb0, 1) 486 | test_ops(0xba, 1) 487 | test_ops(0x10, 3) 488 | test_ops(0xe8, 4) 489 | test_ops(0x37, 4) 490 | test_ops(0xa0, 7) 491 | test_ops(0xa0, 100) 492 | test_ops( 1, 0) 493 | test_ops( 2, 1) 494 | test_ops( 4, 2) 495 | test_ops( 8, 3) 496 | test_ops( 16, 4) 497 | test_ops( 32, 5) 498 | test_ops( 64, 6) 499 | test_ops( 128, 7) 500 | test_ops( 256, 8) 501 | test_ops( 512, 9) 502 | test_ops( 1024, 10) 503 | test_ops( 2048, 11) 504 | test_ops( 4096, 12) 505 | test_ops( 8192, 13) 506 | test_ops( 16384, 14) 507 | test_ops( 32768, 15) 508 | test_ops( 65536, 16) 509 | test_ops( 131072, 17) 510 | test_ops( 262144, 18) 511 | test_ops( 524288, 19) 512 | test_ops(1048576, 20) 513 | test_ops(1048576, 100) 514 | assert_eq(bint(1) << math.mininteger, bint(0)) 515 | assert_eq(bint(1) >> math.mininteger, bint(0)) 516 | assert_eq(bint.brol(1, math.mininteger), bint(1)) 517 | assert_eq(bint.bror(1, math.mininteger), bint(1)) 518 | assert_eq(bint.brol(1, -1), bint.mininteger()) 519 | assert_eq(bint.bror(1, 1), bint.mininteger()) 520 | assert_eq(bint.brol(bint.mininteger(), 1), bint(1)) 521 | assert_eq(bint.bror(bint.mininteger(), -1), bint(1)) 522 | end 523 | 524 | do -- pow 525 | local function test_ipow(x, y) 526 | assert_eq(bint.ipow(x, y):tointeger(), math.floor(x ^ y)) 527 | assert_eq(bint.ipow(x, y):tointeger(), math.floor(x ^ y)) 528 | end 529 | local function test_pow(x, y) 530 | assert_eq(bint(x) ^ bint(y), x ^ y) 531 | assert_eq(bint(x) ^ bint(y), x ^ y) 532 | end 533 | local function test_ops(x, y) 534 | test_ipow(x, y) 535 | test_ipow(-x, y) 536 | test_pow(x, y) 537 | test_pow(-x, y) 538 | test_pow(x, -y) 539 | test_pow(-x, -y) 540 | end 541 | test_ops(0, 0) 542 | test_ops(0, 1) 543 | test_ops(0, 2) 544 | test_ops(0, 15) 545 | test_ops(1, 0) 546 | test_ops(1, 1) 547 | test_ops(1, 2) 548 | test_ops(1, 15) 549 | test_ops(2, 0) 550 | test_ops(2, 1) 551 | test_ops(2, 2) 552 | test_ops(2, 15) 553 | test_ops(7, 4) 554 | test_ops(7, 11) 555 | end 556 | 557 | do --bnot/unm 558 | local function test_bnot(x) 559 | assert_eq((~bint(x)):tointeger(), ~x) 560 | assert_eq((~ ~bint(x)):tointeger(), x) 561 | end 562 | local function test_unm(x) 563 | assert_eq((-bint(x)):tointeger(), -x) 564 | assert_eq((- -bint(x)):tointeger(), x) 565 | end 566 | local function test_inc(x) 567 | assert_eq(bint(x):inc():tointeger(), x + 1) 568 | assert_eq(bint.inc(x + 0.5), x + 1.5) 569 | end 570 | local function test_dec(x) 571 | assert_eq(bint(x):dec():tointeger(), x - 1) 572 | assert_eq(bint.dec(x - 0.5), x - 1.5) 573 | end 574 | local function test_abs(x) 575 | assert_eq(bint(x):abs():tointeger(), math.abs(x)) 576 | assert_eq(bint.abs(x + 0.5), math.abs(x + 0.5)) 577 | end 578 | local function test_floor(x) 579 | assert_eq(bint(x):floor():tointeger(), math.floor(x)) 580 | assert_eq(bint.floor(x + 0.5):tointeger(), math.floor(x + 0.5)) 581 | end 582 | local function test_ceil(x) 583 | assert_eq(bint(x):ceil():tointeger(), math.ceil(x)) 584 | assert_eq(bint.ceil(x + 0.5):tointeger(), math.ceil(x + 0.5)) 585 | end 586 | local function test_ops(x) 587 | test_bnot(x) test_bnot(-x) 588 | test_unm(x) test_unm(-x) 589 | test_inc(x) test_inc(-x) 590 | test_dec(x) test_dec(-x) 591 | test_abs(x) test_abs(-x) 592 | test_floor(x) test_floor(-x) 593 | test_ceil(x) test_ceil(-x) 594 | end 595 | test_ops(0) 596 | test_ops(1) 597 | test_ops(2) 598 | test_ops(15) 599 | test_ops(16) 600 | test_ops(17) 601 | test_ops(0xffffffff) 602 | test_ops(0xfffffffe) 603 | test_ops(0xf505c2) 604 | test_ops(0x9f735a) 605 | test_ops(0xcf7810) 606 | test_ops(0xbbc55f) 607 | end 608 | 609 | do -- idiv/mod 610 | local function test_udiv(x, y) 611 | assert_eq(bint.udiv(x, y):tointeger(), x // y) 612 | end 613 | local function test_div(x, y) 614 | assert_eq(bint(x) / bint(y), x / y) 615 | assert_eq(bint(x) / (y+0.5), x / (y+0.5)) 616 | end 617 | local function test_idiv(x, y) 618 | assert_eq((bint(x) // bint(y)):tointeger(), x // y) 619 | assert_eq(bint(x) // (y+0.5), x // (y+0.5)) 620 | end 621 | local function test_umod(x, y) 622 | assert_eq(bint.umod(x, y):tointeger(), x % y) 623 | end 624 | local function test_mod(x, y) 625 | assert_eq((bint(x) % bint(y)):tointeger(), x % y) 626 | assert_eq(bint(x) % (y+0.5), x % (y+0.5)) 627 | end 628 | local function test_udivmod(x, y) 629 | local quot, rem = bint.udivmod(x, y) 630 | assert_eq(quot:tointeger(), x // y) 631 | assert_eq(rem:tointeger(), x % y) 632 | end 633 | local function test_idivmod(x, y) 634 | local quot, rem = bint.idivmod(x, y) 635 | assert_eq(quot:tointeger(), x // y) 636 | assert_eq(rem:tointeger(), x % y) 637 | end 638 | local function test_ops(x, y) 639 | test_udiv(x, y) 640 | test_idiv(x, y) 641 | test_idiv(x, -y) 642 | test_idiv(-x, -y) 643 | test_idiv(-x, y) 644 | test_idiv(y, y) 645 | test_idiv(-y, -y) 646 | test_div(x, y) 647 | test_div(x, -y) 648 | test_div(-x, -y) 649 | test_div(-x, y) 650 | test_div(y, y) 651 | test_div(-y, -y) 652 | test_umod(x, y) 653 | test_mod(x, y) 654 | test_mod(x, -y) 655 | test_mod(-x, y) 656 | test_mod(-x, -y) 657 | test_mod(y, y) 658 | test_mod(-y, -y) 659 | test_udivmod(x, y) 660 | test_idivmod(x, y) 661 | end 662 | test_ops(0xffffffff, 0xffffffff) 663 | test_ops(0xffffffff, 0x10000) 664 | test_ops(0xffffffff, 0x1000) 665 | test_ops(0xffffffff, 0x100) 666 | test_ops(1000000, 1000) 667 | test_ops(1000000, 10000) 668 | test_ops(1000000, 100000) 669 | test_ops(1000000, 1000000) 670 | test_ops(1000000, 10000000) 671 | test_ops(8, 3) 672 | test_ops(11, 7) 673 | test_ops(28, 7) 674 | test_ops(27, 7) 675 | test_ops(26, 7) 676 | test_ops(25, 7) 677 | test_ops(24, 7) 678 | test_ops(23, 7) 679 | test_ops(22, 7) 680 | test_ops(21, 7) 681 | test_ops(20, 7) 682 | test_ops(0, 12) 683 | test_ops(1, 16) 684 | test_ops(10, 1) 685 | test_ops(1024, 1000) 686 | test_ops(12345678, 16384) 687 | test_ops(0xffffff, 1234) 688 | test_ops(0xfffffff, 1) 689 | test_ops(0xfffffff, 0xef) 690 | test_ops(0xfffffff, 0x10000) 691 | test_ops(0xb36627, 0x0dff95) 692 | test_ops(0xe5a18e, 0x09ff82) 693 | test_ops(0x45edd0, 0x04ff1a) 694 | test_ops(0xe7a344, 0x71ffe8) 695 | test_ops(0xa3a9a1, 0x2ff44) 696 | test_ops(0xc128b2, 0x60ff61) 697 | test_ops(0xdc2254, 0x517fea) 698 | test_ops(0x769c99, 0x2cffda) 699 | test_ops(0xc19076, 0x31ffd4) 700 | end 701 | 702 | do --tdivmod 703 | assert_eq(bint.tdiv( 7, 3 ):tointeger(), 2) 704 | assert_eq(bint.tdiv(-7, 3 ):tointeger(), -2) 705 | assert_eq(bint.tdiv( 7, -3 ):tointeger(), -2) 706 | assert_eq(bint.tdiv(-7, -3 ):tointeger(), 2) 707 | assert_eq(bint.tdiv( 6, 3 ):tointeger(), 2) 708 | assert_eq(bint.tdiv(-6, 3 ):tointeger(), -2) 709 | assert_eq(bint.tdiv( 6, -3 ):tointeger(), -2) 710 | assert_eq(bint.tdiv(-6, -3 ):tointeger(), 2) 711 | 712 | assert_eq(bint.tmod( 7, 3 ):tointeger(), 1) 713 | assert_eq(bint.tmod(-7, 3 ):tointeger(), -1) 714 | assert_eq(bint.tmod( 7, -3 ):tointeger(), 1) 715 | assert_eq(bint.tmod(-7, -3 ):tointeger(), -1) 716 | assert_eq(bint.tmod( 6, 3 ):tointeger(), 0) 717 | assert_eq(bint.tmod(-6, 3 ):tointeger(), 0) 718 | assert_eq(bint.tmod( 6, -3 ):tointeger(), 0) 719 | assert_eq(bint.tmod(-6, -3 ):tointeger(), 0) 720 | 721 | assert_eqf(bint.tdiv(7.5, 2.2), 3.0) assert_eqf(bint.tmod(7.5, 2.2), 0.9) 722 | assert_eqf(bint.tdiv(-7.5, 2.2), -3.0) assert_eqf(bint.tmod(-7.5, 2.2), -0.9) 723 | assert_eqf(bint.tdiv(7.5, -2.2), -3.0) assert_eqf(bint.tmod(7.5, -2.2), 0.9) 724 | assert_eqf(bint.tdiv(-7.5, -2.2), 3.0) assert_eqf(bint.tmod(-7.5, -2.2), -0.9) 725 | end 726 | 727 | do -- upowmod 728 | assert_eq(bint.upowmod(65, 17, 3233):tointeger(), 2790) 729 | assert_eq(bint.upowmod(2790, 413, 3233):tointeger(), 65) 730 | assert_eq(bint.upowmod(2790, 413, 1):tointeger(), 0) 731 | end 732 | end 733 | 734 | test(64) 735 | test(64, 16) 736 | test(64, 8) 737 | test(72, 8) 738 | test(128) 739 | test(160) 740 | test(256) 741 | --------------------------------------------------------------------------------