diff options
Diffstat (limited to 'tex/context/base/l-number.lua')
-rw-r--r-- | tex/context/base/l-number.lua | 414 |
1 files changed, 207 insertions, 207 deletions
diff --git a/tex/context/base/l-number.lua b/tex/context/base/l-number.lua index 7db82173c..001ca31f7 100644 --- a/tex/context/base/l-number.lua +++ b/tex/context/base/l-number.lua @@ -1,207 +1,207 @@ -if not modules then modules = { } end modules ['l-number'] = {
- version = 1.001,
- comment = "companion to luat-lib.mkiv",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- this module will be replaced when we have the bit library .. the number based sets
--- might go away
-
-local tostring, tonumber = tostring, tonumber
-local format, floor, match, rep = string.format, math.floor, string.match, string.rep
-local concat, insert = table.concat, table.insert
-local lpegmatch = lpeg.match
-
-number = number or { }
-local number = number
-
-if bit32 then -- I wonder if this is faster
-
- local btest, bor = bit32.btest, bit32.bor
-
- function number.bit(p)
- return 2 ^ (p - 1) -- 1-based indexing
- end
-
- number.hasbit = btest
- number.setbit = bor
-
- function number.setbit(x,p) -- why not bor?
- return btest(x,p) and x or x + p
- end
-
- function number.clearbit(x,p)
- return btest(x,p) and x - p or x
- end
-
-else
-
- -- http://ricilake.blogspot.com/2007/10/iterating-bits-in-lua.html
-
- function number.bit(p)
- return 2 ^ (p - 1) -- 1-based indexing
- end
-
- function number.hasbit(x, p) -- typical call: if hasbit(x, bit(3)) then ...
- return x % (p + p) >= p
- end
-
- function number.setbit(x, p)
- return (x % (p + p) >= p) and x or x + p
- end
-
- function number.clearbit(x, p)
- return (x % (p + p) >= p) and x - p or x
- end
-
-end
-
--- print(number.tobitstring(8))
--- print(number.tobitstring(14))
--- print(number.tobitstring(66))
--- print(number.tobitstring(0x00))
--- print(number.tobitstring(0xFF))
--- print(number.tobitstring(46260767936,4))
-
-if bit32 then
-
- local bextract = bit32.extract
-
- local t = {
- "0", "0", "0", "0", "0", "0", "0", "0",
- "0", "0", "0", "0", "0", "0", "0", "0",
- "0", "0", "0", "0", "0", "0", "0", "0",
- "0", "0", "0", "0", "0", "0", "0", "0",
- }
-
- function number.tobitstring(b,m)
- -- if really needed we can speed this one up
- -- because small numbers need less extraction
- local n = 32
- for i=0,31 do
- local v = bextract(b,i)
- local k = 32 - i
- if v == 1 then
- n = k
- t[k] = "1"
- else
- t[k] = "0"
- end
- end
- if m then
- m = 33 - m * 8
- if m < 1 then
- m = 1
- end
- return concat(t,"",m)
- elseif n < 8 then
- return concat(t)
- elseif n < 16 then
- return concat(t,"",9)
- elseif n < 24 then
- return concat(t,"",17)
- else
- return concat(t,"",25)
- end
- end
-
-else
-
- function number.tobitstring(n,m)
- if n > 0 then
- local t = { }
- while n > 0 do
- insert(t,1,n % 2 > 0 and 1 or 0)
- n = floor(n/2)
- end
- local nn = 8 - #t % 8
- if nn > 0 and nn < 8 then
- for i=1,nn do
- insert(t,1,0)
- end
- end
- if m then
- m = m * 8 - #t
- if m > 0 then
- insert(t,1,rep("0",m))
- end
- end
- return concat(t)
- elseif m then
- rep("00000000",m)
- else
- return "00000000"
- end
- end
-
-end
-
-function number.valid(str,default)
- return tonumber(str) or default or nil
-end
-
-function number.toevenhex(n)
- local s = format("%X",n)
- if #s % 2 == 0 then
- return s
- else
- return "0" .. s
- end
-end
-
--- a,b,c,d,e,f = number.toset(100101)
---
--- function number.toset(n)
--- return match(tostring(n),"(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)")
--- end
---
--- -- the lpeg way is slower on 8 digits, but faster on 4 digits, some 7.5%
--- -- on
---
--- for i=1,1000000 do
--- local a,b,c,d,e,f,g,h = number.toset(12345678)
--- local a,b,c,d = number.toset(1234)
--- local a,b,c = number.toset(123)
--- local a,b,c = number.toset("123")
--- end
-
-local one = lpeg.C(1-lpeg.S('')/tonumber)^1
-
-function number.toset(n)
- return lpegmatch(one,tostring(n))
-end
-
--- function number.bits(n,zero)
--- local t, i = { }, (zero and 0) or 1
--- while n > 0 do
--- local m = n % 2
--- if m > 0 then
--- insert(t,1,i)
--- end
--- n = floor(n/2)
--- i = i + 1
--- end
--- return t
--- end
---
--- -- a bit faster
-
-local function bits(n,i,...)
- if n > 0 then
- local m = n % 2
- local n = floor(n/2)
- if m > 0 then
- return bits(n, i+1, i, ...)
- else
- return bits(n, i+1, ...)
- end
- else
- return ...
- end
-end
-
-function number.bits(n)
- return { bits(n,1) }
-end
+if not modules then modules = { } end modules ['l-number'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- this module will be replaced when we have the bit library .. the number based sets +-- might go away + +local tostring, tonumber = tostring, tonumber +local format, floor, match, rep = string.format, math.floor, string.match, string.rep +local concat, insert = table.concat, table.insert +local lpegmatch = lpeg.match + +number = number or { } +local number = number + +if bit32 then -- I wonder if this is faster + + local btest, bor = bit32.btest, bit32.bor + + function number.bit(p) + return 2 ^ (p - 1) -- 1-based indexing + end + + number.hasbit = btest + number.setbit = bor + + function number.setbit(x,p) -- why not bor? + return btest(x,p) and x or x + p + end + + function number.clearbit(x,p) + return btest(x,p) and x - p or x + end + +else + + -- http://ricilake.blogspot.com/2007/10/iterating-bits-in-lua.html + + function number.bit(p) + return 2 ^ (p - 1) -- 1-based indexing + end + + function number.hasbit(x, p) -- typical call: if hasbit(x, bit(3)) then ... + return x % (p + p) >= p + end + + function number.setbit(x, p) + return (x % (p + p) >= p) and x or x + p + end + + function number.clearbit(x, p) + return (x % (p + p) >= p) and x - p or x + end + +end + +-- print(number.tobitstring(8)) +-- print(number.tobitstring(14)) +-- print(number.tobitstring(66)) +-- print(number.tobitstring(0x00)) +-- print(number.tobitstring(0xFF)) +-- print(number.tobitstring(46260767936,4)) + +if bit32 then + + local bextract = bit32.extract + + local t = { + "0", "0", "0", "0", "0", "0", "0", "0", + "0", "0", "0", "0", "0", "0", "0", "0", + "0", "0", "0", "0", "0", "0", "0", "0", + "0", "0", "0", "0", "0", "0", "0", "0", + } + + function number.tobitstring(b,m) + -- if really needed we can speed this one up + -- because small numbers need less extraction + local n = 32 + for i=0,31 do + local v = bextract(b,i) + local k = 32 - i + if v == 1 then + n = k + t[k] = "1" + else + t[k] = "0" + end + end + if m then + m = 33 - m * 8 + if m < 1 then + m = 1 + end + return concat(t,"",m) + elseif n < 8 then + return concat(t) + elseif n < 16 then + return concat(t,"",9) + elseif n < 24 then + return concat(t,"",17) + else + return concat(t,"",25) + end + end + +else + + function number.tobitstring(n,m) + if n > 0 then + local t = { } + while n > 0 do + insert(t,1,n % 2 > 0 and 1 or 0) + n = floor(n/2) + end + local nn = 8 - #t % 8 + if nn > 0 and nn < 8 then + for i=1,nn do + insert(t,1,0) + end + end + if m then + m = m * 8 - #t + if m > 0 then + insert(t,1,rep("0",m)) + end + end + return concat(t) + elseif m then + rep("00000000",m) + else + return "00000000" + end + end + +end + +function number.valid(str,default) + return tonumber(str) or default or nil +end + +function number.toevenhex(n) + local s = format("%X",n) + if #s % 2 == 0 then + return s + else + return "0" .. s + end +end + +-- a,b,c,d,e,f = number.toset(100101) +-- +-- function number.toset(n) +-- return match(tostring(n),"(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)") +-- end +-- +-- -- the lpeg way is slower on 8 digits, but faster on 4 digits, some 7.5% +-- -- on +-- +-- for i=1,1000000 do +-- local a,b,c,d,e,f,g,h = number.toset(12345678) +-- local a,b,c,d = number.toset(1234) +-- local a,b,c = number.toset(123) +-- local a,b,c = number.toset("123") +-- end + +local one = lpeg.C(1-lpeg.S('')/tonumber)^1 + +function number.toset(n) + return lpegmatch(one,tostring(n)) +end + +-- function number.bits(n,zero) +-- local t, i = { }, (zero and 0) or 1 +-- while n > 0 do +-- local m = n % 2 +-- if m > 0 then +-- insert(t,1,i) +-- end +-- n = floor(n/2) +-- i = i + 1 +-- end +-- return t +-- end +-- +-- -- a bit faster + +local function bits(n,i,...) + if n > 0 then + local m = n % 2 + local n = floor(n/2) + if m > 0 then + return bits(n, i+1, i, ...) + else + return bits(n, i+1, ...) + end + else + return ... + end +end + +function number.bits(n) + return { bits(n,1) } +end |