684 lines
18 KiB
Lua
684 lines
18 KiB
Lua
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<67>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<67>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
|