安裝Lua最小開發運行環境:
apt-get install lua5.1-0-dev
find / -name lua.h
/home/hanxiaohua/work1/MathTool/lua/lua.h
/usr/include/lua5.1/lua.h
./luatest
./luatest: /usr/lib/x86_64-linux-gnu/liblua5.1.so.0: no version information available (required by ./luatest)
root@ubuntu:/home/cpptest/lua# ./luatest NumberTheory.lua
5!=120
6!=720
7!=5040
8!=40320
9!=362880
10!=3628800
11!=39916800
12!=479001600
4 -4 -4
4 6
totient(37)=36
totient(57)=36
totient(63)=36
totient(74)=36
totient(76)=36
100
7
PowerMod(5,-2,17)=15
PowerMod(5,-1,17)=7
PowerMod(5,0,17)=1
PowerMod(5,1,17)=5
PowerMod(5,2,17)=8
PowerMod(5,4,17)=13
PowerMod(5,8,17)=16
PowerMod(5,16,17)=1
在前30個正整數中,1,8,12,15,16,20,21,24,28,30,沒有原根
lprimroot(2)=1,lprimroot(3)=2,lprimroot(4)=3,lprimroot(5)=2,lprimroot(6)=5,lprimroot(7)=3,lprimroot(9)=2,lprimroot(10)=3,lprimroot(11)=2,lprimroot(13)=2,lprimroot(14)=3,lprimroot(17)=3,lprimroot(18)=5,lprimroot(19)=2,lprimroot(22)=7,lprimroot(23)=5,lprimroot(25)=2,lprimroot(26)=7,lprimroot(27)=2,lprimroot(29)=2,有原根
function Factorial(n)
if n==0 or n==1 then
return 1
else
return n * Factorial(n-1)
end
end
--print("Enter a number : ")
--i = io.read("*number")
for i=5,12,1 do
io.write(i,"!=",Factorial(i),"\n")
end
--求2個整數的最大公約數
function GcdInt(a,b)
if(a*b<0) then
return -GcdInt(math.abs(a),math.abs(b))
end
if(a<b) then
local temp=a
a=b
b=temp
end
if(a%b==0)then
return b
else
return GcdInt(a%b,b)
end
end
local ret=GcdInt(12,32)
local ret1=GcdInt(-12,32)
local ret2=GcdInt(12,-32)
print(ret,ret1,ret2)
function Iscoprime(a,b)
local ret=0
if(GcdInt(a,b)==1)then
ret=1
end
return ret
end
--φ(n)表示不大於n且與n互素的正整數個數、n階循環羣中n階元的個數、本原n次單位根(n次單位原根)的個數、整數模n乘法羣(模n既約剩餘類)(Z/p^nZ)^×中與n互素剩餘類的個數
function Phi(n)
local ret=0
if(n==1)then
return 1
end
for i=1,n-1,1 do
ret=ret+Iscoprime(n,i)
end
return ret
end
--T(n)表示n的正因子的個數、n階循環羣子羣的個數、Z/nZ理想的個數
function Sigma0(n)
local ret=0
for d=1,n,1 do
if(n%d==0)then
ret=ret+1
end
end
return ret
end
--totient(12)=4
--|S(C_12)|=T(12)=|{1,2,3,4,6,12}|=6
print(Phi(12),Sigma0(12))
local v36={37,57,63,74,76}
for i,v in pairs(v36) do
io.write("totient(",v,")=",Phi(v),"\n")
end
function Mod(ret,n)
if(ret<0)then
local ret1=ret+(-ret+1)*n
return ret1%n
end
return ret%n
end
function mod(ret,n)
local raw_mod=ret%n
if (raw_mod==0) then
return 0
elseif (ret>= 0) then
return raw_mod
else
return raw_mod+n
end
end
function inverse_mod_p(u,p)
for i=1,p-1,1 do
if (Mod(u * i, p ) == 1)then
return i
end
end
return nil
--[[
local t1 = 0
local t3 = 0
local q = 0
local u1 = 1
local u3 = u
local v1 = 0
local v3 = p
local inv_v = 0
while( v3 ~= 0) do
q = u3 / v3
t1 = u1 - v1 * q
t3 = u3 - v3 * q
u1 = v1
u3 = v3
v1 = t1
v3 = t3
end
inv_v=mod(u1,p)
if (mod(u * inv_v, p ) ~= 1)then
return 0
end
return inv_v
]]--
end
function PowerMod(a,k,p)
if k<0 then
local a1=inverse_mod_p(a,p)
return PowerMod(a1,-k,p)
end
local ans=1
for i=1,k,1 do
ans=ans*a%p
end
return ans
end
function OrderMod(a,p)
local k=1
while(k<=p) do
if(PowerMod(a,k,p)==1)then
break
end
k=k+1
end
return k
end
function LogMod(b,a,p)
local k=1
while(k<=p) do
if(PowerMod(a,k,p)==b)then
break
end
k=k+1
end
return k
end
print(LogMod(57, 3, 113))
print(inverse_mod_p(5,17))
local bArr={-2,-1,0,1,2,4,8,16}
for i,v in pairs(bArr) do
io.write("PowerMod(5,",v,",17)=",PowerMod(5,v,17),"\n")
end
function is_primitive_root(a,p)
local k=OrderMod(a,p)
return k==Phi(p)
end
--計算模n的最小原根
function PrimitiveRootMod(n)
for a=1,n-1,1 do
local ret=is_primitive_root(a,n)
if(ret)then
return a
end
end
return nil
end
io.write("在前30個正整數中,")
for n=1,30,1 do
if PrimitiveRootMod(n)==nil then
io.write(n,",")
end
end
io.write("沒有原根\n")
for n=1,30,1 do
local ret=PrimitiveRootMod(n)
if ret~=nil then
io.write("lprimroot(",n,")=",ret,",")
end
end
io.write("有原根\n")
test.lua中依賴於宿主程序calllua的Lua代碼:暫無
root@ubuntu:/home/cpptest/lua# g++ -o calllua calllua.cpp -I /usr/include/lua5.1/ -llua5.1
Hello, World!
10+30=40
1 靈智系
2 蠻荒系
3 地脈系
4 天羽系
5 蜚廉系
6 瑞獸系
7 神巫系
8 幽冥系
PHYLE_MAX=8
eWorldPhyle.P_TERRAN=0
eWorldPhyle.PHYLE_MAX=8
0 靈智系
1 蠻荒系
2 地脈系
3 天羽系
4 蜚廉系
5 瑞獸系
6 神巫系
7 幽冥系
(1/17)=1,x=1
(2/17)=1,x=6
(3/17)=-1,x=0
(4/17)=1,x=2
(5/17)=-1,x=0
(6/17)=-1,x=0
(7/17)=-1,x=0
(8/17)=1,x=5
(9/17)=1,x=3
(10/17)=-1,x=0
(11/17)=-1,x=0
(12/17)=-1,x=0
(13/17)=1,x=8
(14/17)=-1,x=0
(15/17)=1,x=7
(16/17)=1,x=4
(17/17)=0,x=0
3 8 8 1
1二次剩餘:[1,2,4,8,9,13,15,16,]
-1二次非剩餘:[3,5,6,7,10,11,12,14,]
0整除:[17,]
10+5=15
-- test.lua
print "Hello, World!"
myName = "beauty girl"
helloTable = {name = "mutou", IQ = 125}
function helloAdd(num1, num2)
return (num1 + num2)
end;
sum=helloAdd(10,30)
print("10+30="..sum)
gszWorldPhyle= {"靈智系", "蠻荒系", "地脈系", "天羽系", "蜚廉系", "瑞獸系", "神巫系", "幽冥系"}
--i 表示索引, v 表示值
for i,v in ipairs(gszWorldPhyle) do
print(i, v)
end
PHYLE_MAX=#gszWorldPhyle
print("PHYLE_MAX="..PHYLE_MAX)
-- 填index=-1從0開始,填index=0或不填index從1開始,……
function CreateEnumTable(tbl, index)
local enumtbl = {}
local enumindex = index or 0
for i, v in ipairs(tbl) do
enumtbl[v] = enumindex + i
end
return enumtbl
end
--[[
種族= 0人型系,1野獸系,2植物系,3飛行系,4昆蟲系,5龍系,6神系,7不死系
]]--
eWorldPhyle = CreateEnumTable({"P_TERRAN", "P_BEAST", "P_PLANTS", "P_FLY", "P_INSECT", "P_DRAGON", "P_PROTOSS", "P_UNDEAD", "PHYLE_MAX"},-1)
print("eWorldPhyle.P_TERRAN="..eWorldPhyle.P_TERRAN)
print("eWorldPhyle.PHYLE_MAX="..eWorldPhyle.PHYLE_MAX)
function getWorldPhyle(Phyle)
return gszWorldPhyle[Phyle+1]
end
for i=eWorldPhyle.P_TERRAN,eWorldPhyle.PHYLE_MAX-1,1 do
local v=getWorldPhyle(i)
print(i,v)
end
--正確的獲取table的長度應該是遍歷,而且要用pairs,不要用ipairs
local function get_len(tb)
local len = 0
for k,v in pairs(tb) do
len= len+1
end
return len
end
--[[
按定義計算二次剩餘和二次非剩餘
x=8,(13/17)=1
x=無解,(5/17)=-1
]]--
function Legendre(a,p)
local x=0
if(a%p==0) then
return 0,x--是p的倍數
end
for i=1,p-1,1 do
if((i*i-a)%p==0) then
x=i
return 1,x--a是p的二次剩餘
end
end
return -1,x--a是p的二次非剩餘
end
local Ret17={[1]={}, [-1]={}, [0]={}}
for i=1,17,1 do
local ret,x=Legendre(i,17)
local str = string.format("(%d/17)=%d,x=%d",i,ret,x)
print(str)
--print(i,ret,x)
table.insert(Ret17[ret],i)
end
print(get_len(Ret17),#Ret17[1], #Ret17[-1], #Ret17[0])
function getRetStr(ret)
local strArr={"二次非剩餘","整除","二次剩餘"}
return strArr[ret+2]
end
for k,v in pairs(Ret17) do
io.write(k..getRetStr(k)..":[")
for k1,v1 in pairs(v) do
io.write(v1,",")
end
print("]")
end
lua中元表的應用例子1:lua複數類
root@ubuntu:/home/cpptest/lua# ./luatest2
./luatest2: /usr/lib/x86_64-linux-gnu/liblua5.1.so.0: no version information available (required by ./luatest2)
4 5
-2 -3
-1 7
0.28 -0.04
c:4 5
The sum is 21
luapythagorean(3,4)=5.000000
-- test2.lua
function add(x,y)
return x+y
end
function pythagorean(a,b)
local c2 = a^2 + b^2
return math.sqrt(c2)
end
function fun(x)
return math.sqrt(math.sqrt(4*x*x+1)-x*x-1)
end
complex={
__add=function(op1,op2)
op = {}
op.x = op1.x + op2.x
op.y = op1.y + op2.y
setmetatable(op,complex)
return op
end,
__sub=function(op1,op2)
op = {}
op.x = op1.x - op2.x
op.y = op1.y - op2.y
setmetatable(op,complex)
return op
end,
__mul=function(op1,op2)
op = {}
op.x = op1.x * op2.x-op1.y * op2.y
op.y = op1.x* op2.y + op2.x* op1.y
setmetatable(op,complex)
return op
end,
__div=function(op1,op2)
op = {}
op.x = (op1.x * op2.x+op1.y * op2.y)/(op2.x * op2.x+op2.y * op2.y)
op.y = (-op1.x* op2.y + op2.x* op1.y)/(op2.x * op2.x+op2.y * op2.y)
setmetatable(op,complex)
return op
end,
create=function(o)
o = o or {}
setmetatable(o,complex)
return o
end
}
a=complex.create{x=1,y=1}
b=complex.create{x=3,y=4}
c = a + b
print(c.x, c.y) -- 輸出 4,5
d = a - b
print(d.x, d.y) -- 輸出 -2,-3
e = a * b
print(e.x, e.y) -- 輸出 -1,7
f = a / b
print(f.x, f.y) -- 輸出 0.28,-0.04
meta={
__add=function(op1,op2)
op = {}
op.x = op1.x + op2.x
op.y = op1.y + op2.y
return op
end
}
a={x=1,y=1}
setmetatable(a,meta)
b={x=3,y=4}
c = a + b
print("c:"..c.x, c.y) -- 輸出 4,5
大家可以參考lua手冊,metatable是被譯作元表,Lua 中的每個值都可以用一個 metatable。這個 metatable 就是一個原始的 Lua table ,它用來定義原始值在特定操作下的行爲。
一個 metatable 可以控制一個對象做數學運算操作、比較操作、連接操作、取長度操作、取下標操作時的行爲,metatable 中還可以定義一個函數,讓 userdata 作垃圾收集時調用它。對於這些操作,Lua 都將其關聯上一個被稱作事件的指定健。當 Lua 需要對一個值發起這些操作中的一個時,它會去檢查值中 metatable 中是否有對應事件。如果有的話,鍵名對應的值(元方法)將控制 Lua 怎樣做這個操作。
metatable通過其包含的函數來給所掛接的table定義一些特殊的操作,包括:
__add: 定義所掛接table的加法操作
__mul: 定義乘法操作
__div: 定義除法操作
__sub: 定義減法操作
__unm: 定義負操作, 即: -table的含義
__tostring: 定義當table作爲tostring()函式之參數被呼叫時的行爲(例如: print(table)時將呼叫tostring(table)作爲輸出結果)
__concat: 定義連接操作(".."運算符)
__index: 定義當table中不存在的key值被試圖獲取時的行爲
__newindex: 定義在table中產生新key值時的行爲
Lua中用表類型模擬複數,x表示實部,y表示虛部;然後把複數相加的邏輯(實部+實部,虛部+虛部)寫進元表內 __add 方法中,因此,(1+1i) + (3+4i) = (4+5i)。元表是普通表變量中的一張隱藏的表,用 setmetatable 函數設置它,想要讀出來則用 getmetatable。
如果我們正在編制一個複數計算程序,需要定義許多複數,那麼能實現一個“永久”的複數類型 (complex)那是再好不過了。在該代碼中,利用 complex.create 創建複數,只需要輸入複數的實部和虛部的值即可,然後可以對複數使用加法運算,加法運算的結果(這裏指 c)也是複數。我們這裏說一個表是複數(表),不僅僅要求該表具有 x,y 兩項數值,而且要具有複數的行爲,類似“相加”、“相減”、“相乘”。。。等等。
Lua基礎知識
常量
變量
a=10
a=2.5
a="諸葛量化"
=是賦值符號,==是等於符號
lua變量必須以字母或者下劃線開頭,區分大小寫
lua的關鍵字不能用作變量名
8種數據類型:
nil、boolean、number、string、function、userdata、thread、table
局部變量由關鍵字local定義的,全局變量沒有被local定義
Lua語言優勢:
小巧、快速、易於嵌入到C語言、與C語言交互方便、易於在線更新
lua、luac一個是運行環境,一個是編譯器
Lua語言調用C語言帶參數的方法:getString
luaL_checkstring(L,1);//獲取傳進來的參數,檢查第1個參數
lua_pushstring(L,buf);壓入棧中
return 1;//指明返回值有1個
Lua語言和C語言的交互機制
lua語言的索引是從1開始的
從上到下是-1、-2、-3……
從下到上是1、2、3、……
數組語言不僅僅是C語言
Lua語言不依賴於數組語言的數據類型
C語言調用Lua語言的方法
Lua語言沒有入口方法
執行Lua中的main方法(無參數、無返回值)
lua_getglobal(L,"main");//Lua棧的第一個位置放進方法
lua_call(L,0,0);//第二個表示傳進參數的個數,第三個表示返回值的個數
方法調用結束後會自動把棧清空
使用C語言執行一個Lua文件
luaL_newstate創建一個lua_State
Lua_openlibs加載庫(print是庫裏面的方法)
dofile(L,"app.lua")
使用C語言執行一段字符串Lua腳本
dostring(L,"print(\"Hello eoe\")","MyScript");