mirror of
https://github.com/rayaman/multi.git
synced 2026-09-05 07:27:35 -04:00
Updated to 1.10.0!
Check changes.md for what was done
This commit is contained in:
@@ -0,0 +1,683 @@
|
||||
RADIX = 10^7 ;
|
||||
RADIX_LEN = math.floor( math.log10 ( RADIX ) ) ;
|
||||
|
||||
BigNum = {} ;
|
||||
BigNum.mt = {} ;
|
||||
|
||||
function BigNum.new( num ) --{{{2
|
||||
local bignum = {} ;
|
||||
setmetatable( bignum , BigNum.mt ) ;
|
||||
BigNum.change( bignum , num ) ;
|
||||
return bignum ;
|
||||
end
|
||||
|
||||
function BigNum.mt.sub( num1 , num2 )
|
||||
local temp = BigNum.new() ;
|
||||
local bnum1 = BigNum.new( num1 ) ;
|
||||
local bnum2 = BigNum.new( num2 ) ;
|
||||
BigNum.sub( bnum1 , bnum2 , temp ) ;
|
||||
return temp ;
|
||||
end
|
||||
function BigNum.mt.mod( num1 , num2 )
|
||||
return BigNum.new(num1 - (num1/num2)*num2)
|
||||
end
|
||||
function BigNum.mt.add( num1 , num2 )
|
||||
local temp = BigNum.new() ;
|
||||
local bnum1 = BigNum.new( num1 ) ;
|
||||
local bnum2 = BigNum.new( num2 ) ;
|
||||
BigNum.add( bnum1 , bnum2 , temp ) ;
|
||||
return temp ;
|
||||
end
|
||||
|
||||
function BigNum.mt.mul( num1 , num2 )
|
||||
local temp = BigNum.new() ;
|
||||
local bnum1 = BigNum.new( num1 ) ;
|
||||
local bnum2 = BigNum.new( num2 ) ;
|
||||
BigNum.mul( bnum1 , bnum2 , temp ) ;
|
||||
return temp ;
|
||||
end
|
||||
|
||||
function BigNum.mt.div( num1 , num2 )
|
||||
local bnum1 = {} ;
|
||||
local bnum2 = {} ;
|
||||
local bnum3 = BigNum.new() ;
|
||||
local bnum4 = BigNum.new() ;
|
||||
bnum1 = BigNum.new( num1 ) ;
|
||||
bnum2 = BigNum.new( num2 ) ;
|
||||
BigNum.div( bnum1 , bnum2 , bnum3 , bnum4 ) ;
|
||||
return bnum3 , bnum4 ;
|
||||
end
|
||||
|
||||
function BigNum.mt.tostring( bnum )
|
||||
local i = 0 ;
|
||||
local j = 0 ;
|
||||
local str = "" ;
|
||||
local temp = "" ;
|
||||
if bnum == nil then
|
||||
return "nil" ;
|
||||
elseif bnum.len > 0 then
|
||||
for i = bnum.len - 2 , 0 , -1 do
|
||||
for j = 0 , RADIX_LEN - string.len( bnum[i] ) - 1 do
|
||||
temp = temp .. '0' ;
|
||||
end
|
||||
temp = temp .. bnum[i] ;
|
||||
end
|
||||
if bnum[bnum.len - 1]==nil then
|
||||
return "nil"
|
||||
end
|
||||
temp = bnum[bnum.len - 1] .. temp ;
|
||||
if bnum.signal == '-' then
|
||||
temp = bnum.signal .. temp ;
|
||||
end
|
||||
return temp ;
|
||||
else
|
||||
return "" ;
|
||||
end
|
||||
end
|
||||
|
||||
function BigNum.mt.pow( num1 , num2 )
|
||||
local bnum1 = BigNum.new( num1 ) ;
|
||||
local bnum2 = BigNum.new( num2 ) ;
|
||||
return BigNum.pow( bnum1 , bnum2 ) ;
|
||||
end
|
||||
|
||||
function BigNum.mt.eq( num1 , num2 )
|
||||
local bnum1 = BigNum.new( num1 ) ;
|
||||
local bnum2 = BigNum.new( num2 ) ;
|
||||
return BigNum.eq( bnum1 , bnum2 ) ;
|
||||
end
|
||||
|
||||
function BigNum.mt.lt( num1 , num2 )
|
||||
local bnum1 = BigNum.new( num1 ) ;
|
||||
local bnum2 = BigNum.new( num2 ) ;
|
||||
return BigNum.lt( bnum1 , bnum2 ) ;
|
||||
end
|
||||
|
||||
function BigNum.mt.le( num1 , num2 )
|
||||
local bnum1 = BigNum.new( num1 ) ;
|
||||
local bnum2 = BigNum.new( num2 ) ;
|
||||
return BigNum.le( bnum1 , bnum2 ) ;
|
||||
end
|
||||
|
||||
function BigNum.mt.unm( num )
|
||||
local ret = BigNum.new( num )
|
||||
if ret.signal == '+' then
|
||||
ret.signal = '-'
|
||||
else
|
||||
ret.signal = '+'
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
BigNum.mt.__metatable = "hidden"
|
||||
BigNum.mt.__tostring = BigNum.mt.tostring ;
|
||||
BigNum.mt.__add = BigNum.mt.add ;
|
||||
BigNum.mt.__sub = BigNum.mt.sub ;
|
||||
BigNum.mt.__mul = BigNum.mt.mul ;
|
||||
BigNum.mt.__div = BigNum.mt.div ;
|
||||
BigNum.mt.__pow = BigNum.mt.pow ;
|
||||
BigNum.mt.__unm = BigNum.mt.unm ;
|
||||
BigNum.mt.__mod = BigNum.mt.mod ;
|
||||
BigNum.mt.__eq = BigNum.mt.eq ;
|
||||
BigNum.mt.__le = BigNum.mt.le ;
|
||||
BigNum.mt.__lt = BigNum.mt.lt ;
|
||||
setmetatable( BigNum.mt, { __index = "inexistent field", __newindex = "not available", __metatable="hidden" } ) ;
|
||||
function BigNum.add( bnum1 , bnum2 , bnum3 )
|
||||
local maxlen = 0 ;
|
||||
local i = 0 ;
|
||||
local carry = 0 ;
|
||||
local signal = '+' ;
|
||||
local old_len = 0 ;
|
||||
--Handle the signals
|
||||
if bnum1 == nil or bnum2 == nil or bnum3 == nil then
|
||||
error("Function BigNum.add: parameter nil") ;
|
||||
elseif bnum1.signal == '-' and bnum2.signal == '+' then
|
||||
bnum1.signal = '+' ;
|
||||
BigNum.sub( bnum2 , bnum1 , bnum3 ) ;
|
||||
|
||||
if not rawequal(bnum1, bnum3) then
|
||||
bnum1.signal = '-' ;
|
||||
end
|
||||
return 0 ;
|
||||
elseif bnum1.signal == '+' and bnum2.signal == '-' then
|
||||
bnum2.signal = '+' ;
|
||||
BigNum.sub( bnum1 , bnum2 , bnum3 ) ;
|
||||
if not rawequal(bnum2, bnum3) then
|
||||
bnum2.signal = '-' ;
|
||||
end
|
||||
return 0 ;
|
||||
elseif bnum1.signal == '-' and bnum2.signal == '-' then
|
||||
signal = '-' ;
|
||||
end
|
||||
--
|
||||
old_len = bnum3.len ;
|
||||
if bnum1.len > bnum2.len then
|
||||
maxlen = bnum1.len ;
|
||||
else
|
||||
maxlen = bnum2.len ;
|
||||
bnum1 , bnum2 = bnum2 , bnum1 ;
|
||||
end
|
||||
--School grade sum
|
||||
for i = 0 , maxlen - 1 do
|
||||
if bnum2[i] ~= nil then
|
||||
bnum3[i] = bnum1[i] + bnum2[i] + carry ;
|
||||
else
|
||||
bnum3[i] = bnum1[i] + carry ;
|
||||
end
|
||||
if bnum3[i] >= RADIX then
|
||||
bnum3[i] = bnum3[i] - RADIX ;
|
||||
carry = 1 ;
|
||||
else
|
||||
carry = 0 ;
|
||||
end
|
||||
end
|
||||
--Update the answer's size
|
||||
if carry == 1 then
|
||||
bnum3[maxlen] = 1 ;
|
||||
end
|
||||
bnum3.len = maxlen + carry ;
|
||||
bnum3.signal = signal ;
|
||||
for i = bnum3.len, old_len do
|
||||
bnum3[i] = nil ;
|
||||
end
|
||||
return 0 ;
|
||||
end
|
||||
|
||||
function BigNum.sub( bnum1 , bnum2 , bnum3 )
|
||||
local maxlen = 0 ;
|
||||
local i = 0 ;
|
||||
local carry = 0 ;
|
||||
local old_len = 0 ;
|
||||
if bnum1 == nil or bnum2 == nil or bnum3 == nil then
|
||||
error("Function BigNum.sub: parameter nil") ;
|
||||
elseif bnum1.signal == '-' and bnum2.signal == '+' then
|
||||
bnum1.signal = '+' ;
|
||||
BigNum.add( bnum1 , bnum2 , bnum3 ) ;
|
||||
bnum3.signal = '-' ;
|
||||
if not rawequal(bnum1, bnum3) then
|
||||
bnum1.signal = '-' ;
|
||||
end
|
||||
return 0 ;
|
||||
elseif bnum1.signal == '-' and bnum2.signal == '-' then
|
||||
bnum1.signal = '+' ;
|
||||
bnum2.signal = '+' ;
|
||||
BigNum.sub( bnum2, bnum1 , bnum3 ) ;
|
||||
if not rawequal(bnum1, bnum3) then
|
||||
bnum1.signal = '-' ;
|
||||
end
|
||||
if not rawequal(bnum2, bnum3) then
|
||||
bnum2.signal = '-' ;
|
||||
end
|
||||
return 0 ;
|
||||
elseif bnum1.signal == '+' and bnum2.signal == '-' then
|
||||
bnum2.signal = '+' ;
|
||||
BigNum.add( bnum1 , bnum2 , bnum3 ) ;
|
||||
if not rawequal(bnum2, bnum3) then
|
||||
bnum2.signal = '-' ;
|
||||
end
|
||||
return 0 ;
|
||||
end
|
||||
--Tests if bnum2 > bnum1
|
||||
if BigNum.compareAbs( bnum1 , bnum2 ) == 2 then
|
||||
BigNum.sub( bnum2 , bnum1 , bnum3 ) ;
|
||||
bnum3.signal = '-' ;
|
||||
return 0 ;
|
||||
else
|
||||
maxlen = bnum1.len ;
|
||||
end
|
||||
old_len = bnum3.len ;
|
||||
bnum3.len = 0 ;
|
||||
--School grade subtraction
|
||||
for i = 0 , maxlen - 1 do
|
||||
if bnum2[i] ~= nil then
|
||||
bnum3[i] = bnum1[i] - bnum2[i] - carry ;
|
||||
else
|
||||
bnum3[i] = bnum1[i] - carry ;
|
||||
end
|
||||
if bnum3[i] < 0 then
|
||||
bnum3[i] = RADIX + bnum3[i] ;
|
||||
carry = 1 ;
|
||||
else
|
||||
carry = 0 ;
|
||||
end
|
||||
|
||||
if bnum3[i] ~= 0 then
|
||||
bnum3.len = i + 1 ;
|
||||
end
|
||||
end
|
||||
bnum3.signal = '+' ;
|
||||
--Check if answer's size if zero
|
||||
if bnum3.len == 0 then
|
||||
bnum3.len = 1 ;
|
||||
bnum3[0] = 0 ;
|
||||
end
|
||||
if carry == 1 then
|
||||
error( "Error in function sub" ) ;
|
||||
end
|
||||
for i = bnum3.len , max( old_len , maxlen - 1 ) do
|
||||
bnum3[i] = nil ;
|
||||
end
|
||||
return 0 ;
|
||||
end
|
||||
|
||||
function BigNum.mul( bnum1 , bnum2 , bnum3 )
|
||||
local i = 0 ; j = 0 ;
|
||||
local temp = BigNum.new( ) ;
|
||||
local temp2 = 0 ;
|
||||
local carry = 0 ;
|
||||
local oldLen = bnum3.len ;
|
||||
if bnum1 == nil or bnum2 == nil or bnum3 == nil then
|
||||
error("Function BigNum.mul: parameter nil") ;
|
||||
--Handle the signals
|
||||
elseif bnum1.signal ~= bnum2.signal then
|
||||
BigNum.mul( bnum1 , -bnum2 , bnum3 ) ;
|
||||
bnum3.signal = '-' ;
|
||||
return 0 ;
|
||||
end
|
||||
bnum3.len = ( bnum1.len ) + ( bnum2.len ) ;
|
||||
--Fill with zeros
|
||||
for i = 1 , bnum3.len do
|
||||
bnum3[i - 1] = 0 ;
|
||||
end
|
||||
--Places nil where passes through this
|
||||
for i = bnum3.len , oldLen do
|
||||
bnum3[i] = nil ;
|
||||
end
|
||||
--School grade multiplication
|
||||
for i = 0 , bnum1.len - 1 do
|
||||
for j = 0 , bnum2.len - 1 do
|
||||
carry = ( bnum1[i] * bnum2[j] + carry ) ;
|
||||
carry = carry + bnum3[i + j] ;
|
||||
bnum3[i + j] = ( carry % RADIX ) ;
|
||||
temp2 = bnum3[i + j] ;
|
||||
carry = math.floor ( carry / RADIX ) ;
|
||||
end
|
||||
if carry ~= 0 then
|
||||
bnum3[i + bnum2.len] = carry ;
|
||||
end
|
||||
carry = 0 ;
|
||||
end
|
||||
|
||||
--Update the answer's size
|
||||
for i = bnum3.len - 1 , 1 , -1 do
|
||||
if bnum3[i] ~= nil and bnum3[i] ~= 0 then
|
||||
break ;
|
||||
else
|
||||
bnum3[i] = nil ;
|
||||
end
|
||||
bnum3.len = bnum3.len - 1 ;
|
||||
end
|
||||
return 0 ;
|
||||
end
|
||||
|
||||
function BigNum.div( bnum1 , bnum2 , bnum3 , bnum4 )
|
||||
local temp = BigNum.new() ;
|
||||
local temp2 = BigNum.new() ;
|
||||
local one = BigNum.new( "1" ) ;
|
||||
local zero = BigNum.new( "0" ) ;
|
||||
--Check division by zero
|
||||
if BigNum.compareAbs( bnum2 , zero ) == 0 then
|
||||
error( "Function BigNum.div: Division by zero" ) ;
|
||||
end
|
||||
--Handle the signals
|
||||
if bnum1 == nil or bnum2 == nil or bnum3 == nil or bnum4 == nil then
|
||||
error( "Function BigNum.div: parameter nil" ) ;
|
||||
elseif bnum1.signal == "+" and bnum2.signal == "-" then
|
||||
bnum2.signal = "+" ;
|
||||
BigNum.div( bnum1 , bnum2 , bnum3 , bnum4 ) ;
|
||||
bnum2.signal = "-" ;
|
||||
bnum3.signal = "-" ;
|
||||
return 0 ;
|
||||
elseif bnum1.signal == "-" and bnum2.signal == "+" then
|
||||
bnum1.signal = "+" ;
|
||||
BigNum.div( bnum1 , bnum2 , bnum3 , bnum4 ) ;
|
||||
bnum1.signal = "-" ;
|
||||
if bnum4 < zero then --Check if remainder is negative
|
||||
BigNum.add( bnum3 , one , bnum3 ) ;
|
||||
BigNum.sub( bnum2 , bnum4 , bnum4 ) ;
|
||||
end
|
||||
bnum3.signal = "-" ;
|
||||
return 0 ;
|
||||
elseif bnum1.signal == "-" and bnum2.signal == "-" then
|
||||
bnum1.signal = "+" ;
|
||||
bnum2.signal = "+" ;
|
||||
BigNum.div( bnum1 , bnum2 , bnum3 , bnum4 ) ;
|
||||
bnum1.signal = "-" ;
|
||||
if bnum4 < zero then --Check if remainder is negative
|
||||
BigNum.add( bnum3 , one , bnum3 ) ;
|
||||
BigNum.sub( bnum2 , bnum4 , bnum4 ) ;
|
||||
end
|
||||
bnum2.signal = "-" ;
|
||||
return 0 ;
|
||||
end
|
||||
temp.len = bnum1.len - bnum2.len - 1 ;
|
||||
|
||||
--Reset variables
|
||||
BigNum.change( bnum3 , "0" ) ;
|
||||
BigNum.change( bnum4 , "0" ) ;
|
||||
|
||||
BigNum.copy( bnum1 , bnum4 ) ;
|
||||
|
||||
--Check if can continue dividing
|
||||
while( BigNum.compareAbs( bnum4 , bnum2 ) ~= 2 ) do
|
||||
if bnum4[bnum4.len - 1] >= bnum2[bnum2.len - 1] then
|
||||
BigNum.put( temp , math.floor( bnum4[bnum4.len - 1] / bnum2[bnum2.len - 1] ) , bnum4.len - bnum2.len ) ;
|
||||
temp.len = bnum4.len - bnum2.len + 1 ;
|
||||
else
|
||||
BigNum.put( temp , math.floor( ( bnum4[bnum4.len - 1] * RADIX + bnum4[bnum4.len - 2] ) / bnum2[bnum2.len -1] ) , bnum4.len - bnum2.len - 1 ) ;
|
||||
temp.len = bnum4.len - bnum2.len ;
|
||||
end
|
||||
|
||||
if bnum4.signal ~= bnum2.signal then
|
||||
temp.signal = "-";
|
||||
else
|
||||
temp.signal = "+";
|
||||
end
|
||||
BigNum.add( temp , bnum3 , bnum3 ) ;
|
||||
temp = temp * bnum2 ;
|
||||
BigNum.sub( bnum4 , temp , bnum4 ) ;
|
||||
end
|
||||
|
||||
--Update if the remainder is negative
|
||||
if bnum4.signal == '-' then
|
||||
decr( bnum3 ) ;
|
||||
BigNum.add( bnum2 , bnum4 , bnum4 ) ;
|
||||
end
|
||||
return 0 ;
|
||||
end
|
||||
|
||||
function BigNum.pow( bnum1 , bnum2 )
|
||||
local n = BigNum.new( bnum2 ) ;
|
||||
local y = BigNum.new( 1 ) ;
|
||||
local z = BigNum.new( bnum1 ) ;
|
||||
local zero = BigNum.new( "0" ) ;
|
||||
if bnum2 < zero then
|
||||
error( "Function BigNum.exp: domain error" ) ;
|
||||
elseif bnum2 == zero then
|
||||
return y ;
|
||||
end
|
||||
while 1 do
|
||||
if ( n[0] % 2 ) == 0 then
|
||||
n = n / 2 ;
|
||||
else
|
||||
n = n / 2 ;
|
||||
y = z * y ;
|
||||
if n == zero then
|
||||
return y ;
|
||||
end
|
||||
end
|
||||
z = z * z ;
|
||||
end
|
||||
end
|
||||
-- Português :
|
||||
BigNum.exp = BigNum.pow
|
||||
|
||||
function BigNum.gcd( bnum1 , bnum2 )
|
||||
local a = {} ;
|
||||
local b = {} ;
|
||||
local c = {} ;
|
||||
local d = {} ;
|
||||
local zero = {} ;
|
||||
zero = BigNum.new( "0" ) ;
|
||||
if bnum1 == zero or bnum2 == zero then
|
||||
return BigNum.new( "1" ) ;
|
||||
end
|
||||
a = BigNum.new( bnum1 ) ;
|
||||
b = BigNum.new( bnum2 ) ;
|
||||
a.signal = '+' ;
|
||||
b.signal = '+' ;
|
||||
c = BigNum.new() ;
|
||||
d = BigNum.new() ;
|
||||
while b > zero do
|
||||
BigNum.div( a , b , c , d ) ;
|
||||
a , b , d = b , d , a ;
|
||||
end
|
||||
return a ;
|
||||
end
|
||||
-- Português:
|
||||
BigNum.mmc = BigNum.gcd
|
||||
|
||||
function BigNum.eq( bnum1 , bnum2 )
|
||||
if BigNum.compare( bnum1 , bnum2 ) == 0 then
|
||||
return true ;
|
||||
else
|
||||
return false ;
|
||||
end
|
||||
end
|
||||
|
||||
function BigNum.lt( bnum1 , bnum2 )
|
||||
if BigNum.compare( bnum1 , bnum2 ) == 2 then
|
||||
return true ;
|
||||
else
|
||||
return false ;
|
||||
end
|
||||
end
|
||||
|
||||
function BigNum.le( bnum1 , bnum2 )
|
||||
local temp = -1 ;
|
||||
temp = BigNum.compare( bnum1 , bnum2 )
|
||||
if temp == 0 or temp == 2 then
|
||||
return true ;
|
||||
else
|
||||
return false ;
|
||||
end
|
||||
end
|
||||
|
||||
function BigNum.compareAbs( bnum1 , bnum2 )
|
||||
if bnum1 == nil or bnum2 == nil then
|
||||
error("Function compare: parameter nil") ;
|
||||
elseif bnum1.len > bnum2.len then
|
||||
return 1 ;
|
||||
elseif bnum1.len < bnum2.len then
|
||||
return 2 ;
|
||||
else
|
||||
local i ;
|
||||
for i = bnum1.len - 1 , 0 , -1 do
|
||||
if bnum1[i] > bnum2[i] then
|
||||
return 1 ;
|
||||
elseif bnum1[i] < bnum2[i] then
|
||||
return 2 ;
|
||||
end
|
||||
end
|
||||
end
|
||||
return 0 ;
|
||||
end
|
||||
|
||||
function BigNum.compare( bnum1 , bnum2 )
|
||||
local signal = 0 ;
|
||||
|
||||
if bnum1 == nil or bnum2 == nil then
|
||||
error("Funtion BigNum.compare: parameter nil") ;
|
||||
elseif bnum1.signal == '+' and bnum2.signal == '-' then
|
||||
return 1 ;
|
||||
elseif bnum1.signal == '-' and bnum2.signal == '+' then
|
||||
return 2 ;
|
||||
elseif bnum1.signal == '-' and bnum2.signal == '-' then
|
||||
signal = 1 ;
|
||||
end
|
||||
if bnum1.len > bnum2.len then
|
||||
return 1 + signal ;
|
||||
elseif bnum1.len < bnum2.len then
|
||||
return 2 - signal ;
|
||||
else
|
||||
local i ;
|
||||
for i = bnum1.len - 1 , 0 , -1 do
|
||||
if bnum1[i] > bnum2[i] then
|
||||
return 1 + signal ;
|
||||
elseif bnum1[i] < bnum2[i] then
|
||||
return 2 - signal ;
|
||||
end
|
||||
end
|
||||
end
|
||||
return 0 ;
|
||||
end
|
||||
|
||||
function BigNum.copy( bnum1 , bnum2 )
|
||||
if bnum1 ~= nil and bnum2 ~= nil then
|
||||
local i ;
|
||||
for i = 0 , bnum1.len - 1 do
|
||||
bnum2[i] = bnum1[i] ;
|
||||
end
|
||||
bnum2.len = bnum1.len ;
|
||||
else
|
||||
error("Function BigNum.copy: parameter nil") ;
|
||||
end
|
||||
end
|
||||
|
||||
function BigNum.change( bnum1 , num )
|
||||
local j = 0 ;
|
||||
local len = 0 ;
|
||||
local num = num ;
|
||||
local l ;
|
||||
local oldLen = 0 ;
|
||||
if bnum1 == nil then
|
||||
error( "BigNum.change: parameter nil" ) ;
|
||||
elseif type( bnum1 ) ~= "table" then
|
||||
error( "BigNum.change: parameter error, type unexpected" ) ;
|
||||
elseif num == nil then
|
||||
bnum1.len = 1 ;
|
||||
bnum1[0] = 0 ;
|
||||
bnum1.signal = "+";
|
||||
elseif type( num ) == "table" and num.len ~= nil then --check if num is a big number
|
||||
--copy given table to the new one
|
||||
for i = 0 , num.len do
|
||||
bnum1[i] = num[i] ;
|
||||
end
|
||||
if num.signal ~= '-' and num.signal ~= '+' then
|
||||
bnum1.signal = '+' ;
|
||||
else
|
||||
bnum1.signal = num.signal ;
|
||||
end
|
||||
oldLen = bnum1.len ;
|
||||
bnum1.len = num.len ;
|
||||
elseif type( num ) == "string" or type( num ) == "number" then
|
||||
if string.sub( num , 1 , 1 ) == '+' or string.sub( num , 1 , 1 ) == '-' then
|
||||
bnum1.signal = string.sub( num , 1 , 1 ) ;
|
||||
num = string.sub(num, 2) ;
|
||||
else
|
||||
bnum1.signal = '+' ;
|
||||
end
|
||||
num = string.gsub( num , " " , "" ) ;
|
||||
local sf = string.find( num , "e" ) ;
|
||||
--Handles if the number is in exp notation
|
||||
if sf ~= nil then
|
||||
num = string.gsub( num , "%." , "" ) ;
|
||||
local e = string.sub( num , sf + 1 ) ;
|
||||
e = tonumber(e) ;
|
||||
if e ~= nil and e > 0 then
|
||||
e = tonumber(e) ;
|
||||
else
|
||||
error( "Function BigNum.change: string is not a valid number" ) ;
|
||||
end
|
||||
num = string.sub( num , 1 , sf - 2 ) ;
|
||||
for i = string.len( num ) , e do
|
||||
num = num .. "0" ;
|
||||
end
|
||||
else
|
||||
sf = string.find( num , "%." ) ;
|
||||
if sf ~= nil then
|
||||
num = string.sub( num , 1 , sf - 1 ) ;
|
||||
end
|
||||
end
|
||||
|
||||
l = string.len( num ) ;
|
||||
oldLen = bnum1.len ;
|
||||
if (l > RADIX_LEN) then
|
||||
local mod = l-( math.floor( l / RADIX_LEN ) * RADIX_LEN ) ;
|
||||
for i = 1 , l-mod, RADIX_LEN do
|
||||
bnum1[j] = tonumber( string.sub( num, -( i + RADIX_LEN - 1 ) , -i ) );
|
||||
--Check if string dosn't represents a number
|
||||
if bnum1[j] == nil then
|
||||
error( "Function BigNum.change: string is not a valid number" ) ;
|
||||
bnum1.len = 0 ;
|
||||
return 1 ;
|
||||
end
|
||||
j = j + 1 ;
|
||||
len = len + 1 ;
|
||||
end
|
||||
if (mod ~= 0) then
|
||||
bnum1[j] = tonumber( string.sub( num , 1 , mod ) ) ;
|
||||
bnum1.len = len + 1 ;
|
||||
else
|
||||
bnum1.len = len ;
|
||||
end
|
||||
--Eliminate trailing zeros
|
||||
for i = bnum1.len - 1 , 1 , -1 do
|
||||
if bnum1[i] == 0 then
|
||||
bnum1[i] = nil ;
|
||||
bnum1.len = bnum1.len - 1 ;
|
||||
else
|
||||
break ;
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
-- string.len(num) <= RADIX_LEN
|
||||
bnum1[j] = tonumber( num ) ;
|
||||
bnum1.len = 1 ;
|
||||
end
|
||||
else
|
||||
error( "Function BigNum.change: parameter error, type unexpected" ) ;
|
||||
end
|
||||
|
||||
--eliminates the deprecated higher order 'algarisms'
|
||||
if oldLen ~= nil then
|
||||
for i = bnum1.len , oldLen do
|
||||
bnum1[i] = nil ;
|
||||
end
|
||||
end
|
||||
|
||||
return 0 ;
|
||||
end
|
||||
|
||||
function BigNum.put( bnum , int , pos )
|
||||
if bnum == nil then
|
||||
error("Function BigNum.put: parameter nil") ;
|
||||
end
|
||||
local i = 0 ;
|
||||
for i = 0 , pos - 1 do
|
||||
bnum[i] = 0 ;
|
||||
end
|
||||
bnum[pos] = int ;
|
||||
for i = pos + 1 , bnum.len do
|
||||
bnum[i] = nil ;
|
||||
end
|
||||
bnum.len = pos ;
|
||||
return 0 ;
|
||||
end
|
||||
|
||||
--printraw{{{2
|
||||
function printraw( bnum )
|
||||
local i = 0 ;
|
||||
if bnum == nil then
|
||||
error( "Function printraw: parameter nil" ) ;
|
||||
end
|
||||
while 1 == 1 do
|
||||
if bnum[i] == nil then
|
||||
io.write( ' len '..bnum.len ) ;
|
||||
if i ~= bnum.len then
|
||||
io.write( ' ERRO!!!!!!!!' ) ;
|
||||
end
|
||||
io.write( "\n" ) ;
|
||||
return 0 ;
|
||||
end
|
||||
io.write( 'r'..bnum[i] ) ;
|
||||
i = i + 1 ;
|
||||
end
|
||||
end
|
||||
--max{{{2
|
||||
function max( int1 , int2 )
|
||||
if int1 > int2 then
|
||||
return int1 ;
|
||||
else
|
||||
return int2 ;
|
||||
end
|
||||
end
|
||||
|
||||
--decr{{{2
|
||||
function decr( bnum1 )
|
||||
local temp = {} ;
|
||||
temp = BigNum.new( "1" ) ;
|
||||
BigNum.sub( bnum1 , temp , bnum1 ) ;
|
||||
return 0 ;
|
||||
end
|
||||
@@ -0,0 +1,227 @@
|
||||
require( "bin.numbers.BigNum" ) ;
|
||||
|
||||
BigRat = {} ;
|
||||
BigRat.mt = {} ;
|
||||
function BigRat.new( num1 , num2 ) --{{{2
|
||||
local bigrat = {} ;
|
||||
local f ;
|
||||
setmetatable(bigrat, BigRat.mt) ;
|
||||
if type( num1 ) == "table" then
|
||||
if num1.num ~= nil and num1.den ~= nil then
|
||||
bigrat.num = BigNum.new( num1.num ) ;
|
||||
bigrat.den = BigNum.new( num1.den ) ;
|
||||
else
|
||||
bigrat.num = BigNum.new( num1 ) ;
|
||||
bigrat.den = BigNum.new( "1" ) ;
|
||||
end
|
||||
elseif num1 ~= nil then
|
||||
if num2 == nil then
|
||||
bigrat.den = BigNum.new( "1" ) ;
|
||||
else
|
||||
bigrat.den = BigNum.new( num2 ) ;
|
||||
end
|
||||
bigrat.num = BigNum.new( num1 ) ;
|
||||
else
|
||||
bigrat.den = BigNum.new( ) ;
|
||||
bigrat.num = BigNum.new( ) ;
|
||||
end
|
||||
|
||||
--Update the signals
|
||||
if bigrat.den.signal == "-" then
|
||||
if bigrat.num.signal == "-" then
|
||||
bigrat.num.signal = "+" ;
|
||||
else
|
||||
bigrat.num.signal = "-" ;
|
||||
end
|
||||
bigrat.den.signal = "+" ;
|
||||
end
|
||||
|
||||
return bigrat ;
|
||||
end
|
||||
|
||||
function BigRat.mt.sub( num1 , num2 )
|
||||
local temp = BigRat.new() ;
|
||||
local brat1 = BigRat.new( num1 ) ;
|
||||
local brat2 = BigRat.new( num2 ) ;
|
||||
BigRat.sub( brat1 , brat2 , temp ) ;
|
||||
return temp ;
|
||||
end
|
||||
|
||||
function BigRat.mt.add( num1 , num2 )
|
||||
local temp = BigRat.new() ;
|
||||
local brat1 = BigRat.new( num1 ) ;
|
||||
local brat2 = BigRat.new( num2 ) ;
|
||||
BigRat.add( brat1 , brat2 , temp ) ;
|
||||
return temp ;
|
||||
end
|
||||
|
||||
function BigRat.mt.mul( num1 , num2 )
|
||||
local temp = BigRat.new() ;
|
||||
local brat1 = BigRat.new( num1 ) ;
|
||||
local brat2 = BigRat.new( num2 ) ;
|
||||
BigRat.mul( brat1 , brat2 , temp ) ;
|
||||
return temp ;
|
||||
end
|
||||
|
||||
function BigRat.mt.div( num1 , num2 )
|
||||
local brat1 = BigRat.new( num1 ) ;
|
||||
local brat2 = BigRat.new( num2 ) ;
|
||||
local brat3 = BigRat.new() ;
|
||||
local brat4 = BigRat.new() ;
|
||||
BigRat.div( brat1 , brat2 , brat3 , brat4 ) ;
|
||||
return brat3 , brat4 ;
|
||||
end
|
||||
|
||||
function BigRat.mt.tostring( brat )
|
||||
BigRat.simplify( brat ) ;
|
||||
return BigNum.mt.tostring( brat.num ) .. " / " .. BigNum.mt.tostring( brat.den ) ;
|
||||
end
|
||||
|
||||
function BigRat.mt.pow ( num1 , num2 )
|
||||
local brat1 = BigRat.new( num1 ) ;
|
||||
local brat2 = BigRat.new( num2 ) ;
|
||||
return BigRat.pow( brat1 , brat2 )
|
||||
end
|
||||
|
||||
function BigRat.mt.eq ( num1 , num2 )
|
||||
return BigRat.eq( num1 , num2 )
|
||||
end
|
||||
|
||||
function BigRat.mt.lt ( num1 , num2 )
|
||||
return BigRat.lt( num1 , num2 )
|
||||
end
|
||||
|
||||
function BigRat.mt.le ( num1 , num2 )
|
||||
return BigRat.le( num1 , num2 )
|
||||
end
|
||||
|
||||
function BigRat.mt.unm ( num )
|
||||
local ret = BigRat.new( num )
|
||||
if ret.num.signal == '-' then
|
||||
ret.num.signal = '+'
|
||||
else
|
||||
ret.num.signal = '-'
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
BigRat.mt.__metatable = "hidden"
|
||||
BigRat.mt.__tostring = BigRat.mt.tostring
|
||||
BigRat.mt.__add = BigRat.mt.add
|
||||
BigRat.mt.__sub = BigRat.mt.sub
|
||||
BigRat.mt.__mul = BigRat.mt.mul
|
||||
BigRat.mt.__div = BigRat.mt.div
|
||||
BigRat.mt.__pow = BigRat.mt.pow
|
||||
BigRat.mt.__unm = BigRat.mt.unm
|
||||
BigRat.mt.__eq = BigRat.mt.eq
|
||||
BigRat.mt.__le = BigRat.mt.le
|
||||
BigRat.mt.__lt = BigRat.mt.lt
|
||||
setmetatable( BigRat.mt, { __index = "inexistent field", __newindex = "not available", __metatable="hidden" } ) ;
|
||||
function BigRat.add( brat1 , brat2 , brat3 )
|
||||
brat3.den = brat1.den * brat2.den ;
|
||||
brat3.num = ( brat1.num * brat2.den ) + ( brat2.num * brat1.den ) ;
|
||||
return brat3 ;
|
||||
end
|
||||
function BigRat.sub( brat1 , brat2 , brat3 )
|
||||
brat3.den = brat1.den * brat2.den ;
|
||||
brat3.num = ( brat1.num * brat2.den ) - ( brat2.num * brat1.den ) ;
|
||||
return brat3 ;
|
||||
end
|
||||
|
||||
function BigRat.mul( brat1 , brat2 , brat3 )
|
||||
brat3.num = brat1.num * brat2.num ;
|
||||
brat3.den = brat1.den * brat2.den ;
|
||||
return 0 ;
|
||||
end
|
||||
|
||||
function BigRat.div( brat1 , brat2 , brat3 )
|
||||
brat3.num = brat1.num * brat2.den ;
|
||||
brat3.den = brat1.den * brat2.num ;
|
||||
return brat3 ;
|
||||
end
|
||||
|
||||
function BigRat.pow( bnum1 , bnum2 )
|
||||
if bnum1 == nil or bnum2 == nil then
|
||||
error( "Function BigRat.pow: parameter nil" ) ;
|
||||
end
|
||||
local x = BigRat.new( "8" ) ;
|
||||
local n = BigRat.new( bnum2.den ) ;
|
||||
local n2 ;
|
||||
local y = BigRat.new( ) ;
|
||||
local i ;
|
||||
local temp = BigRat.new( ) ;
|
||||
|
||||
BigRat.simplify( bnum2 ) ;
|
||||
temp.num = BigNum.exp( bnum1.num , bnum2.num ) ;
|
||||
temp.den = BigNum.exp( bnum1.den , bnum2.num ) ;
|
||||
n2 = n - 1 ;
|
||||
|
||||
for i = 0 , 4 do
|
||||
y.num = x.num ^ n2.num ;
|
||||
y.den = x.den ^ n2.num ;
|
||||
x = (( temp / y ) + ( n2 * x )) / n ;
|
||||
end
|
||||
return x ;
|
||||
end
|
||||
|
||||
function BigRat.simplify( brat )
|
||||
if brat == nil then
|
||||
error( "Function BigRat.simplify: parameter nil" ) ;
|
||||
end
|
||||
local gcd = BigNum.new( ) ;
|
||||
local temp = BigRat.new( brat ) ;
|
||||
local devnull = BigNum.new( ) ;
|
||||
local zero = BigNum.new( "0" ) ;
|
||||
--Check if numerator is zero
|
||||
if BigNum.compareAbs( brat.num , zero ) == 0 then
|
||||
brat.den = BigNum.new( "1" ) ;
|
||||
return 0 ;
|
||||
end
|
||||
gcd = BigNum.gcd( brat.num , brat.den ) ;
|
||||
BigNum.div( temp.num , gcd , brat.num , devnull ) ;
|
||||
BigNum.div( temp.den , gcd , brat.den , devnull ) ;
|
||||
--Update the signal
|
||||
if brat.num.signal == '-' and brat.den.signal == '-' then
|
||||
brat.num.signal = '+' ;
|
||||
brat.den.signal = '+' ;
|
||||
end
|
||||
return 0 ;
|
||||
end
|
||||
|
||||
function BigRat.eq( brat1 , brat2 )
|
||||
if BigRat.compare( brat1 , brat2 ) == 0 then
|
||||
return true ;
|
||||
else
|
||||
return false ;
|
||||
end
|
||||
end
|
||||
|
||||
function BigRat.lt( brat1 , brat2 )
|
||||
if BigRat.compare( brat1 , brat2 ) == 2 then
|
||||
return true ;
|
||||
else
|
||||
return false ;
|
||||
end
|
||||
end
|
||||
|
||||
function BigRat.le( brat1 , brat2 )
|
||||
local temp = -1 ;
|
||||
temp = BigRat.compare( brat1 , brat2 )
|
||||
if temp == 0 or temp == 2 then
|
||||
return true ;
|
||||
else
|
||||
return false ;
|
||||
end
|
||||
end
|
||||
|
||||
function BigRat.compare( bnum1 , bnum2 )
|
||||
local temp ;
|
||||
temp = bnum1 - bnum2 ;
|
||||
if temp.num[0] == 0 and temp.num.len == 1 then --Check if is zero
|
||||
return 0 ;
|
||||
elseif temp.num.signal == "-" then
|
||||
return 2 ;
|
||||
else
|
||||
return 1 ;
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,191 @@
|
||||
local bits={}
|
||||
bits.data=''
|
||||
bits.t='bits'
|
||||
bits.Type='bits'
|
||||
bits.__index = bits
|
||||
bits.__tostring=function(self) return self.data end
|
||||
bits.__len=function(self) return (#self.data)/8 end
|
||||
local floor,insert = math.floor, table.insert
|
||||
function bits.newBitBuffer(n)
|
||||
--
|
||||
end
|
||||
function bits.newConverter(bitsIn,bitsOut)
|
||||
local c={}
|
||||
--
|
||||
end
|
||||
function basen(n,b)
|
||||
if not b or b == 10 then return tostring(n) end
|
||||
local digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
local t = {}
|
||||
local sign = ""
|
||||
if n < 0 then
|
||||
sign = "-"
|
||||
n = -n
|
||||
end
|
||||
repeat
|
||||
local d = n % b + 1
|
||||
n = n / b
|
||||
insert(t, 1, digits:sub(d,d))
|
||||
until n == 0
|
||||
return sign .. table.concat(t,"")
|
||||
end
|
||||
bits.ref={}
|
||||
function bits.newByte(d)
|
||||
local c={}
|
||||
if type(d)=="string" then
|
||||
if #d>1 or #d<1 then
|
||||
error("A byte must be one character!")
|
||||
else
|
||||
c.data=string.byte(d)
|
||||
end
|
||||
elseif type(d)=="number" then
|
||||
if d>255 or d<0 then
|
||||
error("A byte must be between 0 and 255!")
|
||||
else
|
||||
c.data=d
|
||||
end
|
||||
else
|
||||
error("cannot use type "..type(d).." as an argument! Takes only strings or numbers!")
|
||||
end
|
||||
c.__index=function(self,k)
|
||||
if k>=0 and k<9 then
|
||||
if self.data==0 then
|
||||
return 0
|
||||
elseif self.data==255 then
|
||||
return 1
|
||||
else
|
||||
return bits.ref[self.data][k]
|
||||
end
|
||||
end
|
||||
end
|
||||
c.__tostring=function(self)
|
||||
return bits.ref[tostring(self.data)]
|
||||
end
|
||||
setmetatable(c,c)
|
||||
return c
|
||||
end
|
||||
function bits.newByteArray(s)
|
||||
local c={}
|
||||
if type(s)~="string" then
|
||||
error("Must be a string type or bin/buffer type")
|
||||
elseif type(s)=="table" then
|
||||
if s.t=="sink" or s.t=="buffer" or s.t=="bin" then
|
||||
local data=s:getData()
|
||||
for i=1,#data do
|
||||
c[#c+1]=bits.newByte(data:sub(i,i))
|
||||
end
|
||||
else
|
||||
error("Must be a string type or bin/buffer type")
|
||||
end
|
||||
else
|
||||
for i=1,#s do
|
||||
c[#c+1]=bits.newByte(s:sub(i,i))
|
||||
end
|
||||
end
|
||||
return c
|
||||
end
|
||||
function bits.new(n,binary)
|
||||
local temp={}
|
||||
temp.t="bits"
|
||||
temp.Type="bits"
|
||||
if type(n)=="string" then
|
||||
if binary then
|
||||
temp.data=n:match("[10]+")
|
||||
else
|
||||
local t={}
|
||||
for i=#n,1,-1 do
|
||||
table.insert(t,bits:conv(string.byte(n,i)))
|
||||
end
|
||||
temp.data=table.concat(t)
|
||||
end
|
||||
elseif type(n)=="number" or type(n)=="table" then
|
||||
temp.data=basen(n,2)
|
||||
end
|
||||
if #temp.data%8~=0 then
|
||||
temp.data=string.rep('0',8-#temp.data%8)..temp.data
|
||||
end
|
||||
setmetatable(temp, bits)
|
||||
return temp
|
||||
end
|
||||
for i=0,255 do
|
||||
local d=bits.new(i).data
|
||||
bits.ref[i]={d:match("(%d)(%d)(%d)(%d)(%d)(%d)(%d)(%d)")}
|
||||
bits.ref[tostring(i)]=d
|
||||
bits.ref[d]=i
|
||||
bits.ref["\255"..string.char(i)]=d
|
||||
end
|
||||
function bits.numToBytes(n,fit,func)
|
||||
local num=string.reverse(bits.new(n):toSbytes())
|
||||
local ref={["num"]=num,["fit"]=fit}
|
||||
if fit then
|
||||
if fit<#num then
|
||||
if func then
|
||||
print("Warning: attempting to store a number that takes up more space than allotted! Using provided method!")
|
||||
func(ref)
|
||||
else
|
||||
print("Warning: attempting to store a number that takes up more space than allotted!")
|
||||
end
|
||||
return ref.num:sub(1,ref.fit)
|
||||
elseif fit==#num then
|
||||
return string.reverse(num)
|
||||
else
|
||||
return string.reverse(string.rep("\0",fit-#num)..num)
|
||||
end
|
||||
else
|
||||
return string.reverse(num)
|
||||
end
|
||||
end
|
||||
function bits:conv(n)
|
||||
local tab={}
|
||||
while n>=1 do
|
||||
table.insert(tab,n%2)
|
||||
n=math.floor(n/2)
|
||||
end
|
||||
local str=string.reverse(table.concat(tab))
|
||||
if #str%8~=0 or #str==0 then
|
||||
str=string.rep('0',8-#str%8)..str
|
||||
end
|
||||
return str
|
||||
end
|
||||
function bits:tonumber(s,e)
|
||||
if s==0 then
|
||||
return tonumber(self.data,2)
|
||||
end
|
||||
s=s or 1
|
||||
return tonumber(string.sub(self.data,(8*(s-1))+1,8*s),2) or error('Bounds!')
|
||||
end
|
||||
function bits:isover()
|
||||
return #self.data>8
|
||||
end
|
||||
function bits:flipbits()
|
||||
tab={}
|
||||
for i=1,#self.data do
|
||||
if string.sub(self.data,i,i)=='1' then
|
||||
table.insert(tab,'0')
|
||||
else
|
||||
table.insert(tab,'1')
|
||||
end
|
||||
end
|
||||
self.data=table.concat(tab)
|
||||
end
|
||||
function bits:tobytes()
|
||||
local tab={}
|
||||
for i=self:getbytes(),1,-1 do
|
||||
table.insert(tab,string.char(self:tonumber(i)))
|
||||
end
|
||||
return bin.new(table.concat(tab))
|
||||
end
|
||||
function bits:toSbytes()
|
||||
local tab={}
|
||||
for i=self:getbytes(),1,-1 do
|
||||
table.insert(tab,string.char(self:tonumber(i)))
|
||||
end
|
||||
return table.concat(tab)
|
||||
end
|
||||
function bits:getBin()
|
||||
return self.data
|
||||
end
|
||||
function bits:getbytes()
|
||||
return #self.data/8
|
||||
end
|
||||
return bits
|
||||
@@ -0,0 +1,244 @@
|
||||
local binNum=require("bin.numbers.BigNum")
|
||||
local infinabits={}
|
||||
infinabits.data=''
|
||||
infinabits.t='infinabits'
|
||||
infinabits.Type='infinabits'
|
||||
infinabits.__index = infinabits
|
||||
infinabits.__tostring=function(self) return self.data end
|
||||
infinabits.__len=function(self) return (#self.data)/8 end
|
||||
local floor,insert = math.floor, table.insert
|
||||
function basen(n,b)
|
||||
n=BigNum.new(n)
|
||||
if not b or b == 10 then return tostring(n) end
|
||||
local digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
local t = {}
|
||||
local sign = ""
|
||||
if n < BigNum.new(0) then
|
||||
sign = "-"
|
||||
n = -n
|
||||
end
|
||||
repeat
|
||||
local d = tonumber(tostring(n % b)) + 1
|
||||
n = n / b
|
||||
insert(t, 1, digits:sub(d,d))
|
||||
until n == BigNum.new(0)
|
||||
return sign .. table.concat(t,"")
|
||||
end
|
||||
function base2to10(num)
|
||||
local n=BigNum.new(0)
|
||||
for i = #num-1,0,-1 do
|
||||
nn=BigNum.new(num:sub(i+1,i+1))*(BigNum.new(2)^((#num-i)-1))
|
||||
n=n+nn
|
||||
end
|
||||
return n
|
||||
end
|
||||
function infinabits.newBitBuffer(n)
|
||||
-- WIP
|
||||
end
|
||||
function infinabits.newConverter(bitsIn,bitsOut)
|
||||
local c={}
|
||||
-- WIP
|
||||
end
|
||||
infinabits.ref={}
|
||||
function infinabits.newByte(d)-- WIP
|
||||
local c={}
|
||||
if type(d)=="string" then
|
||||
if #d>1 or #d<1 then
|
||||
error("A byte must be one character!")
|
||||
else
|
||||
c.data=string.byte(d)
|
||||
end
|
||||
elseif type(d)=="number" then
|
||||
if d>255 or d<0 then
|
||||
error("A byte must be between 0 and 255!")
|
||||
else
|
||||
c.data=d
|
||||
end
|
||||
else
|
||||
error("cannot use type "..type(d).." as an argument! Takes only strings or numbers!")
|
||||
end
|
||||
c.__index=function(self,k)
|
||||
if k>=0 and k<9 then
|
||||
if self.data==0 then
|
||||
return 0
|
||||
elseif self.data==255 then
|
||||
return 1
|
||||
else
|
||||
return infinabits.ref[self.data][k]
|
||||
end
|
||||
end
|
||||
end
|
||||
c.__tostring=function(self)
|
||||
return infinabits.ref[tostring(self.data)]
|
||||
end
|
||||
setmetatable(c,c)
|
||||
return c
|
||||
end
|
||||
function infinabits.newByteArray(s)-- WIP
|
||||
local c={}
|
||||
if type(s)~="string" then
|
||||
error("Must be a string type or bin/buffer type")
|
||||
elseif type(s)=="table" then
|
||||
if s.t=="sink" or s.t=="buffer" or s.t=="bin" then
|
||||
local data=s:getData()
|
||||
for i=1,#data do
|
||||
c[#c+1]=infinabits.newByte(data:sub(i,i))
|
||||
end
|
||||
else
|
||||
error("Must be a string type or bin/buffer type")
|
||||
end
|
||||
else
|
||||
for i=1,#s do
|
||||
c[#c+1]=infinabits.newByte(s:sub(i,i))
|
||||
end
|
||||
end
|
||||
return c
|
||||
end
|
||||
function infinabits.new(n,binary)
|
||||
local temp={}
|
||||
temp.t="infinabits"
|
||||
temp.Type="infinabits"
|
||||
if type(n)=="string" then
|
||||
if binary then
|
||||
temp.data=n:match("[10]+")
|
||||
else
|
||||
local t={}
|
||||
for i=#n,1,-1 do
|
||||
table.insert(t,infinabits:conv(string.byte(n,i)))
|
||||
end
|
||||
temp.data=table.concat(t)
|
||||
end
|
||||
elseif type(n)=="number" or type(n)=="table" then
|
||||
temp.data=basen(tostring(n),2)
|
||||
end
|
||||
if #temp.data%8~=0 then
|
||||
temp.data=string.rep('0',8-#temp.data%8)..temp.data
|
||||
end
|
||||
setmetatable(temp, infinabits)
|
||||
return temp
|
||||
end
|
||||
for i=0,255 do
|
||||
local d=infinabits.new(i).data
|
||||
infinabits.ref[i]={d:match("(%d)(%d)(%d)(%d)(%d)(%d)(%d)(%d)")}
|
||||
infinabits.ref[tostring(i)]=d
|
||||
infinabits.ref[d]=i
|
||||
infinabits.ref["\255"..string.char(i)]=d
|
||||
end
|
||||
function infinabits.numToBytes(n,fit,func)
|
||||
local num=string.reverse(infinabits.new(BigNum.new(n)):toSbytes())
|
||||
local ref={["num"]=num,["fit"]=fit}
|
||||
if fit then
|
||||
if fit<#num then
|
||||
if func then
|
||||
print("Warning: attempting to store a number that takes up more space than allotted! Using provided method!")
|
||||
func(ref)
|
||||
else
|
||||
print("Warning: attempting to store a number that takes up more space than allotted!")
|
||||
end
|
||||
return ref.num:sub(1,ref.fit)
|
||||
elseif fit==#num then
|
||||
return string.reverse(num)
|
||||
else
|
||||
return string.reverse(string.rep("\0",fit-#num)..num)
|
||||
end
|
||||
else
|
||||
return string.reverse(num)
|
||||
end
|
||||
end
|
||||
function infinabits.numToBytes(n,fit,fmt,func)
|
||||
if fmt=="%e" then
|
||||
local num=string.reverse(infinabits.new(BigNum.new(n)):toSbytes())
|
||||
local ref={["num"]=num,["fit"]=fit}
|
||||
if fit then
|
||||
if fit<#num then
|
||||
if func then
|
||||
print("Warning: attempting to store a number that takes up more space than allotted! Using provided method!")
|
||||
func(ref)
|
||||
else
|
||||
print("Warning: attempting to store a number that takes up more space than allotted!")
|
||||
end
|
||||
return ref.num:sub(1,ref.fit)
|
||||
elseif fit==#num then
|
||||
return num
|
||||
else
|
||||
return string.rep("\0",fit-#num)..num
|
||||
end
|
||||
else
|
||||
return num
|
||||
end
|
||||
|
||||
else
|
||||
local num=string.reverse(infinabits.new(BigNum.new(n)):toSbytes())
|
||||
local ref={["num"]=num,["fit"]=fit}
|
||||
if fit then
|
||||
if fit<#num then
|
||||
if func then
|
||||
print("Warning: attempting to store a number that takes up more space than allotted! Using provided method!")
|
||||
func(ref)
|
||||
else
|
||||
print("Warning: attempting to store a number that takes up more space than allotted!")
|
||||
end
|
||||
return ref.num:sub(1,ref.fit)
|
||||
elseif fit==#num then
|
||||
return string.reverse(num)
|
||||
else
|
||||
return string.reverse(string.rep("\0",fit-#num)..num)
|
||||
end
|
||||
else
|
||||
return string.reverse(num)
|
||||
end
|
||||
end
|
||||
end
|
||||
function infinabits:conv(n)
|
||||
local tab={}
|
||||
local one=BigNum.new(1)
|
||||
local n=BigNum.new(n)
|
||||
while n>=one do
|
||||
table.insert(tab,tonumber(tostring(n%2)))
|
||||
n=n/2
|
||||
end
|
||||
local str=string.reverse(table.concat(tab))
|
||||
if #str%8~=0 or #str==0 then
|
||||
str=string.rep('0',8-#str%8)..str
|
||||
end
|
||||
return str
|
||||
end
|
||||
function infinabits:tonumber(s)
|
||||
if s==0 then
|
||||
return tonumber(self.data,2)
|
||||
end
|
||||
s=s or 1
|
||||
return tonumber(tostring(base2to10(string.sub(self.data,(8*(s-1))+1,8*s)))) or error('Bounds!')
|
||||
end
|
||||
function infinabits:isover()
|
||||
return #self.data>8
|
||||
end
|
||||
function infinabits:flipbits()
|
||||
tab={}
|
||||
local s=self.data
|
||||
s=s:gsub("1","_")
|
||||
s=s:gsub("0","1")
|
||||
s=s:gsub("_","0")
|
||||
self.data=s
|
||||
end
|
||||
function infinabits:tobytes()
|
||||
local tab={}
|
||||
for i=self:getbytes(),1,-1 do
|
||||
table.insert(tab,string.char(self:tonumber(i)))
|
||||
end
|
||||
return bin.new(table.concat(tab))
|
||||
end
|
||||
function infinabits:toSbytes()
|
||||
local tab={}
|
||||
for i=self:getbytes(),1,-1 do
|
||||
table.insert(tab,string.char(self:tonumber(i)))
|
||||
end
|
||||
return table.concat(tab)
|
||||
end
|
||||
function infinabits:getBin()
|
||||
return self.data
|
||||
end
|
||||
function infinabits:getbytes()
|
||||
return #self.data/8
|
||||
end
|
||||
return infinabits
|
||||
@@ -0,0 +1,333 @@
|
||||
--[[
|
||||
LICENSE
|
||||
|
||||
(c) 2008-2011 David Manura. Licensed under the same terms as Lua (MIT).
|
||||
--]]
|
||||
|
||||
local M = {_TYPE='module', _NAME='bit.numberlua', _VERSION='0.3.1.20120131'}
|
||||
|
||||
local floor = math.floor
|
||||
|
||||
local MOD = 2^32
|
||||
local MODM = MOD-1
|
||||
|
||||
local function memoize(f)
|
||||
local mt = {}
|
||||
local t = setmetatable({}, mt)
|
||||
function mt:__index(k)
|
||||
local v = f(k); t[k] = v
|
||||
return v
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
local function make_bitop_uncached(t, m)
|
||||
local function bitop(a, b)
|
||||
local res,p = 0,1
|
||||
while a ~= 0 and b ~= 0 do
|
||||
local am, bm = a%m, b%m
|
||||
res = res + t[am][bm]*p
|
||||
a = (a - am) / m
|
||||
b = (b - bm) / m
|
||||
p = p*m
|
||||
end
|
||||
res = res + (a+b)*p
|
||||
return res
|
||||
end
|
||||
return bitop
|
||||
end
|
||||
|
||||
local function make_bitop(t)
|
||||
local op1 = make_bitop_uncached(t,2^1)
|
||||
local op2 = memoize(function(a)
|
||||
return memoize(function(b)
|
||||
return op1(a, b)
|
||||
end)
|
||||
end)
|
||||
return make_bitop_uncached(op2, 2^(t.n or 1))
|
||||
end
|
||||
|
||||
-- ok? probably not if running on a 32-bit int Lua number type platform
|
||||
function M.tobit(x)
|
||||
return x % 2^32
|
||||
end
|
||||
|
||||
M.bxor = make_bitop {[0]={[0]=0,[1]=1},[1]={[0]=1,[1]=0}, n=4}
|
||||
local bxor = M.bxor
|
||||
|
||||
function M.bnot(a) return MODM - a end
|
||||
local bnot = M.bnot
|
||||
|
||||
function M.band(a,b) return ((a+b) - bxor(a,b))/2 end
|
||||
local band = M.band
|
||||
|
||||
function M.bor(a,b) return MODM - band(MODM - a, MODM - b) end
|
||||
local bor = M.bor
|
||||
|
||||
local lshift, rshift -- forward declare
|
||||
|
||||
function M.rshift(a,disp) -- Lua5.2 insipred
|
||||
if disp < 0 then return lshift(a,-disp) end
|
||||
return floor(a % 2^32 / 2^disp)
|
||||
end
|
||||
rshift = M.rshift
|
||||
|
||||
function M.lshift(a,disp) -- Lua5.2 inspired
|
||||
if disp < 0 then return rshift(a,-disp) end
|
||||
return (a * 2^disp) % 2^32
|
||||
end
|
||||
lshift = M.lshift
|
||||
|
||||
function M.tohex(x, n) -- BitOp style
|
||||
n = n or 8
|
||||
local up
|
||||
if n <= 0 then
|
||||
if n == 0 then return '' end
|
||||
up = true
|
||||
n = - n
|
||||
end
|
||||
x = band(x, 16^n-1)
|
||||
return ('%0'..n..(up and 'X' or 'x')):format(x)
|
||||
end
|
||||
local tohex = M.tohex
|
||||
|
||||
function M.extract(n, field, width) -- Lua5.2 inspired
|
||||
width = width or 1
|
||||
return band(rshift(n, field), 2^width-1)
|
||||
end
|
||||
local extract = M.extract
|
||||
|
||||
function M.replace(n, v, field, width) -- Lua5.2 inspired
|
||||
width = width or 1
|
||||
local mask1 = 2^width-1
|
||||
v = band(v, mask1) -- required by spec?
|
||||
local mask = bnot(lshift(mask1, field))
|
||||
return band(n, mask) + lshift(v, field)
|
||||
end
|
||||
local replace = M.replace
|
||||
|
||||
function M.bswap(x) -- BitOp style
|
||||
local a = band(x, 0xff); x = rshift(x, 8)
|
||||
local b = band(x, 0xff); x = rshift(x, 8)
|
||||
local c = band(x, 0xff); x = rshift(x, 8)
|
||||
local d = band(x, 0xff)
|
||||
return lshift(lshift(lshift(a, 8) + b, 8) + c, 8) + d
|
||||
end
|
||||
local bswap = M.bswap
|
||||
|
||||
function M.rrotate(x, disp) -- Lua5.2 inspired
|
||||
disp = disp % 32
|
||||
local low = band(x, 2^disp-1)
|
||||
return rshift(x, disp) + lshift(low, 32-disp)
|
||||
end
|
||||
local rrotate = M.rrotate
|
||||
|
||||
function M.lrotate(x, disp) -- Lua5.2 inspired
|
||||
return rrotate(x, -disp)
|
||||
end
|
||||
local lrotate = M.lrotate
|
||||
|
||||
M.rol = M.lrotate -- LuaOp inspired
|
||||
M.ror = M.rrotate -- LuaOp insipred
|
||||
|
||||
|
||||
function M.arshift(x, disp) -- Lua5.2 inspired
|
||||
local z = rshift(x, disp)
|
||||
if x >= 0x80000000 then z = z + lshift(2^disp-1, 32-disp) end
|
||||
return z
|
||||
end
|
||||
local arshift = M.arshift
|
||||
|
||||
function M.btest(x, y) -- Lua5.2 inspired
|
||||
return band(x, y) ~= 0
|
||||
end
|
||||
|
||||
M.bit32 = {} -- Lua 5.2 'bit32' compatibility
|
||||
|
||||
|
||||
local function bit32_bnot(x)
|
||||
return (-1 - x) % MOD
|
||||
end
|
||||
M.bit32.bnot = bit32_bnot
|
||||
|
||||
local function bit32_bxor(a, b, c, ...)
|
||||
local z
|
||||
if b then
|
||||
a = a % MOD
|
||||
b = b % MOD
|
||||
z = bxor(a, b)
|
||||
if c then
|
||||
z = bit32_bxor(z, c, ...)
|
||||
end
|
||||
return z
|
||||
elseif a then
|
||||
return a % MOD
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
M.bit32.bxor = bit32_bxor
|
||||
|
||||
local function bit32_band(a, b, c, ...)
|
||||
local z
|
||||
if b then
|
||||
a = a % MOD
|
||||
b = b % MOD
|
||||
z = ((a+b) - bxor(a,b)) / 2
|
||||
if c then
|
||||
z = bit32_band(z, c, ...)
|
||||
end
|
||||
return z
|
||||
elseif a then
|
||||
return a % MOD
|
||||
else
|
||||
return MODM
|
||||
end
|
||||
end
|
||||
M.bit32.band = bit32_band
|
||||
|
||||
local function bit32_bor(a, b, c, ...)
|
||||
local z
|
||||
if b then
|
||||
a = a % MOD
|
||||
b = b % MOD
|
||||
z = MODM - band(MODM - a, MODM - b)
|
||||
if c then
|
||||
z = bit32_bor(z, c, ...)
|
||||
end
|
||||
return z
|
||||
elseif a then
|
||||
return a % MOD
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
M.bit32.bor = bit32_bor
|
||||
|
||||
function M.bit32.btest(...)
|
||||
return bit32_band(...) ~= 0
|
||||
end
|
||||
|
||||
function M.bit32.lrotate(x, disp)
|
||||
return lrotate(x % MOD, disp)
|
||||
end
|
||||
|
||||
function M.bit32.rrotate(x, disp)
|
||||
return rrotate(x % MOD, disp)
|
||||
end
|
||||
|
||||
function M.bit32.lshift(x,disp)
|
||||
if disp > 31 or disp < -31 then return 0 end
|
||||
return lshift(x % MOD, disp)
|
||||
end
|
||||
|
||||
function M.bit32.rshift(x,disp)
|
||||
if disp > 31 or disp < -31 then return 0 end
|
||||
return rshift(x % MOD, disp)
|
||||
end
|
||||
|
||||
function M.bit32.arshift(x,disp)
|
||||
x = x % MOD
|
||||
if disp >= 0 then
|
||||
if disp > 31 then
|
||||
return (x >= 0x80000000) and MODM or 0
|
||||
else
|
||||
local z = rshift(x, disp)
|
||||
if x >= 0x80000000 then z = z + lshift(2^disp-1, 32-disp) end
|
||||
return z
|
||||
end
|
||||
else
|
||||
return lshift(x, -disp)
|
||||
end
|
||||
end
|
||||
|
||||
function M.bit32.extract(x, field, ...)
|
||||
local width = ... or 1
|
||||
if field < 0 or field > 31 or width < 0 or field+width > 32 then error 'out of range' end
|
||||
x = x % MOD
|
||||
return extract(x, field, ...)
|
||||
end
|
||||
|
||||
function M.bit32.replace(x, v, field, ...)
|
||||
local width = ... or 1
|
||||
if field < 0 or field > 31 or width < 0 or field+width > 32 then error 'out of range' end
|
||||
x = x % MOD
|
||||
v = v % MOD
|
||||
return replace(x, v, field, ...)
|
||||
end
|
||||
|
||||
M.bit = {} -- LuaBitOp "bit" compatibility
|
||||
|
||||
function M.bit.tobit(x)
|
||||
x = x % MOD
|
||||
if x >= 0x80000000 then x = x - MOD end
|
||||
return x
|
||||
end
|
||||
local bit_tobit = M.bit.tobit
|
||||
|
||||
function M.bit.tohex(x, ...)
|
||||
return tohex(x % MOD, ...)
|
||||
end
|
||||
|
||||
function M.bit.bnot(x)
|
||||
return bit_tobit(bnot(x % MOD))
|
||||
end
|
||||
|
||||
local function bit_bor(a, b, c, ...)
|
||||
if c then
|
||||
return bit_bor(bit_bor(a, b), c, ...)
|
||||
elseif b then
|
||||
return bit_tobit(bor(a % MOD, b % MOD))
|
||||
else
|
||||
return bit_tobit(a)
|
||||
end
|
||||
end
|
||||
M.bit.bor = bit_bor
|
||||
|
||||
local function bit_band(a, b, c, ...)
|
||||
if c then
|
||||
return bit_band(bit_band(a, b), c, ...)
|
||||
elseif b then
|
||||
return bit_tobit(band(a % MOD, b % MOD))
|
||||
else
|
||||
return bit_tobit(a)
|
||||
end
|
||||
end
|
||||
M.bit.band = bit_band
|
||||
|
||||
local function bit_bxor(a, b, c, ...)
|
||||
if c then
|
||||
return bit_bxor(bit_bxor(a, b), c, ...)
|
||||
elseif b then
|
||||
return bit_tobit(bxor(a % MOD, b % MOD))
|
||||
else
|
||||
return bit_tobit(a)
|
||||
end
|
||||
end
|
||||
M.bit.bxor = bit_bxor
|
||||
|
||||
function M.bit.lshift(x, n)
|
||||
return bit_tobit(lshift(x % MOD, n % 32))
|
||||
end
|
||||
|
||||
function M.bit.rshift(x, n)
|
||||
return bit_tobit(rshift(x % MOD, n % 32))
|
||||
end
|
||||
|
||||
function M.bit.arshift(x, n)
|
||||
return bit_tobit(arshift(x % MOD, n % 32))
|
||||
end
|
||||
|
||||
function M.bit.rol(x, n)
|
||||
return bit_tobit(lrotate(x % MOD, n % 32))
|
||||
end
|
||||
|
||||
function M.bit.ror(x, n)
|
||||
return bit_tobit(rrotate(x % MOD, n % 32))
|
||||
end
|
||||
|
||||
function M.bit.bswap(x)
|
||||
return bit_tobit(bswap(x % MOD))
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -0,0 +1,232 @@
|
||||
--[[----------------------------------------
|
||||
Random
|
||||
Not all of this is mine
|
||||
------------------------------------------]]
|
||||
--[[------------------------------------
|
||||
RandomLua v0.3.1
|
||||
Pure Lua Pseudo-Random Numbers Generator
|
||||
Under the MIT license.
|
||||
copyright(c) 2011 linux-man
|
||||
--]]------------------------------------
|
||||
|
||||
local math_floor = math.floor
|
||||
|
||||
local function normalize(n)
|
||||
return n % 0x80000000
|
||||
end
|
||||
|
||||
local function bit_and(a, b)
|
||||
local r = 0
|
||||
local m = 0
|
||||
for m = 0, 31 do
|
||||
if (a % 2 == 1) and (b % 2 == 1) then r = r + 2^m end
|
||||
if a % 2 ~= 0 then a = a - 1 end
|
||||
if b % 2 ~= 0 then b = b - 1 end
|
||||
a = a / 2 b = b / 2
|
||||
end
|
||||
return normalize(r)
|
||||
end
|
||||
|
||||
local function bit_or(a, b)
|
||||
local r = 0
|
||||
local m = 0
|
||||
for m = 0, 31 do
|
||||
if (a % 2 == 1) or (b % 2 == 1) then r = r + 2^m end
|
||||
if a % 2 ~= 0 then a = a - 1 end
|
||||
if b % 2 ~= 0 then b = b - 1 end
|
||||
a = a / 2 b = b / 2
|
||||
end
|
||||
return normalize(r)
|
||||
end
|
||||
|
||||
local function bit_xor(a, b)
|
||||
local r = 0
|
||||
local m = 0
|
||||
for m = 0, 31 do
|
||||
if a % 2 ~= b % 2 then r = r + 2^m end
|
||||
if a % 2 ~= 0 then a = a - 1 end
|
||||
if b % 2 ~= 0 then b = b - 1 end
|
||||
a = a / 2 b = b / 2
|
||||
end
|
||||
return normalize(r)
|
||||
end
|
||||
|
||||
local function seed()
|
||||
return normalize(os.time())
|
||||
end
|
||||
|
||||
--Mersenne twister
|
||||
local mersenne_twister = {}
|
||||
mersenne_twister.__index = mersenne_twister
|
||||
|
||||
function mersenne_twister:randomseed(s)
|
||||
if not s then s = seed() end
|
||||
self.mt[0] = normalize(s)
|
||||
for i = 1, 623 do
|
||||
self.mt[i] = normalize(0x6c078965 * bit_xor(self.mt[i-1], math_floor(self.mt[i-1] / 0x40000000)) + i)
|
||||
end
|
||||
end
|
||||
|
||||
function mersenne_twister:random(a, b)
|
||||
local y
|
||||
if self.index == 0 then
|
||||
for i = 0, 623 do
|
||||
y = self.mt[(i + 1) % 624] % 0x80000000
|
||||
self.mt[i] = bit_xor(self.mt[(i + 397) % 624], math_floor(y / 2))
|
||||
if y % 2 ~= 0 then self.mt[i] = bit_xor(self.mt[i], 0x9908b0df) end
|
||||
end
|
||||
end
|
||||
y = self.mt[self.index]
|
||||
y = bit_xor(y, math_floor(y / 0x800))
|
||||
y = bit_xor(y, bit_and(normalize(y * 0x80), 0x9d2c5680))
|
||||
y = bit_xor(y, bit_and(normalize(y * 0x8000), 0xefc60000))
|
||||
y = bit_xor(y, math_floor(y / 0x40000))
|
||||
self.index = (self.index + 1) % 624
|
||||
if not a then return y / 0x80000000
|
||||
elseif not b then
|
||||
if a == 0 then return y
|
||||
else return 1 + (y % a)
|
||||
end
|
||||
else
|
||||
return a + (y % (b - a + 1))
|
||||
end
|
||||
end
|
||||
|
||||
local function twister(s)
|
||||
local temp = {}
|
||||
setmetatable(temp, mersenne_twister)
|
||||
temp.mt = {}
|
||||
temp.index = 0
|
||||
temp:randomseed(s)
|
||||
return temp
|
||||
end
|
||||
|
||||
--Linear Congruential Generator
|
||||
local linear_congruential_generator = {}
|
||||
linear_congruential_generator.__index = linear_congruential_generator
|
||||
|
||||
function linear_congruential_generator:random(a, b)
|
||||
local y = (self.a * self.x + self.c) % self.m
|
||||
self.x = y
|
||||
if not a then return y / 0x10000
|
||||
elseif not b then
|
||||
if a == 0 then return y
|
||||
else return 1 + (y % a) end
|
||||
else
|
||||
return a + (y % (b - a + 1))
|
||||
end
|
||||
end
|
||||
|
||||
function linear_congruential_generator:randomseed(s)
|
||||
if not s then s = seed() end
|
||||
self.x = normalize(s)
|
||||
end
|
||||
|
||||
local function lcg(s, r)
|
||||
local temp = {}
|
||||
setmetatable(temp, linear_congruential_generator)
|
||||
temp.a, temp.c, temp.m = 1103515245, 12345, 0x10000 --from Ansi C
|
||||
if r then
|
||||
if r == 'nr' then temp.a, temp.c, temp.m = 1664525, 1013904223, 0x10000 --from Numerical Recipes.
|
||||
elseif r == 'mvc' then temp.a, temp.c, temp.m = 214013, 2531011, 0x10000 end--from MVC
|
||||
end
|
||||
temp:randomseed(s)
|
||||
return temp
|
||||
end
|
||||
|
||||
-- Multiply-with-carry
|
||||
local multiply_with_carry = {}
|
||||
multiply_with_carry.__index = multiply_with_carry
|
||||
|
||||
function multiply_with_carry:random(a, b)
|
||||
local m = self.m
|
||||
local t = self.a * self.x + self.c
|
||||
local y = t % m
|
||||
self.x = y
|
||||
self.c = math_floor(t / m)
|
||||
if not a then return y / 0x10000
|
||||
elseif not b then
|
||||
if a == 0 then return y
|
||||
else return 1 + (y % a) end
|
||||
else
|
||||
return a + (y % (b - a + 1))
|
||||
end
|
||||
end
|
||||
|
||||
function multiply_with_carry:randomseed(s)
|
||||
if not s then s = seed() end
|
||||
self.c = self.ic
|
||||
self.x = normalize(s)
|
||||
end
|
||||
|
||||
local function mwc(s, r)
|
||||
local temp = {}
|
||||
setmetatable(temp, multiply_with_carry)
|
||||
temp.a, temp.c, temp.m = 1103515245, 12345, 0x10000 --from Ansi C
|
||||
if r then
|
||||
if r == 'nr' then temp.a, temp.c, temp.m = 1664525, 1013904223, 0x10000 --from Numerical Recipes.
|
||||
elseif r == 'mvc' then temp.a, temp.c, temp.m = 214013, 2531011, 0x10000 end--from MVC
|
||||
end
|
||||
temp.ic = temp.c
|
||||
temp:randomseed(s)
|
||||
return temp
|
||||
end
|
||||
-- Little bind for the methods: My code starts
|
||||
local randomGen={}
|
||||
randomGen.__index=randomGen
|
||||
function randomGen:new(s)
|
||||
local temp={}
|
||||
setmetatable(temp,randomGen)
|
||||
temp[1]=twister()
|
||||
temp[2]=lcg()
|
||||
temp[3]=mwc()
|
||||
temp.pos=1
|
||||
for i=1,3 do
|
||||
temp[i]:randomseed(s)
|
||||
end
|
||||
return temp
|
||||
end
|
||||
function randomGen:randomseed(s)
|
||||
self.pos=1
|
||||
self[1]:randomseed(s)
|
||||
self[2]:randomseed(s)
|
||||
self[3]:randomseed(s)
|
||||
end
|
||||
function randomGen:randomInt(a,b)
|
||||
local t=self[self.pos]:random(a,b)
|
||||
self.pos=self.pos+1
|
||||
if self.pos>3 then
|
||||
self.pos=1
|
||||
end
|
||||
return t
|
||||
end
|
||||
function randomGen:newND(a,b,s)
|
||||
if not(a) or not(b) then error('You must include a range!') end
|
||||
local temp=randomGen:new(s)
|
||||
temp.a=a
|
||||
temp.b=b
|
||||
temp.range=b-a+1
|
||||
temp.dups={no=0}
|
||||
function temp:nextInt()
|
||||
local t=self:randomInt(self.a,self.b)
|
||||
if self.dups[t]==nil then
|
||||
self.dups[t]=true
|
||||
self.dups.no=self.dups.no+1
|
||||
else
|
||||
return self:nextInt()
|
||||
end
|
||||
if self.dups.no==self.range then
|
||||
function self:nextInt()
|
||||
return 1,true
|
||||
end
|
||||
return t
|
||||
else
|
||||
return t
|
||||
end
|
||||
end
|
||||
function temp:nextIInt()
|
||||
return function() return self:nextInt() end
|
||||
end
|
||||
return temp
|
||||
end
|
||||
return randomGen
|
||||
Reference in New Issue
Block a user