317 lines
No EOL
11 KiB
HTML
317 lines
No EOL
11 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<HTML><HEAD><TITLE>lua-users wiki: Math Library Tutorial</TITLE>
|
|
<LINK TYPE="text/css" REL="stylesheet" HREF="/styles/main.css">
|
|
</HEAD>
|
|
<BODY ><table width="100%" border="0"> <tr><td align=left width="100%"><h1><a href="/cgi-bin/wiki.pl?action=search&string=MathLibraryTutorial&body=1" title="List pages referring to MathLibraryTutorial">Math Library Tutorial</a></h1></td><td align=right>
|
|
<table cellpadding="0" cellspacing="0" border="0" width="1%">
|
|
<tbody>
|
|
<tr>
|
|
<td><a href="/">
|
|
<img src="/images/nav-logo.png" alt="lua-users home" width="177" height="40" border="0"></a></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
|
<tbody>
|
|
<tr>
|
|
<td><img src="/images/nav-elbow.png" alt="" width="48" height="40"></td>
|
|
<td nowrap valign="middle" width="100%">
|
|
<a href="/wiki/" class="nav">wiki</a></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<form method="post" action="/wiki/FindPage" enctype="application/x-www-form-urlencoded" style="display:inline; margin:0;">
|
|
<input type="hidden" name="action" value="search" /><input type="text" name="string" size="20" style="" id="search_query1" /><input type="hidden" name="title" value="1" /><input type="submit" name=".submit" value="Search" /><input type="hidden" name="body" value="on" /></form></td></tr> </table>
|
|
<br clear=all>
|
|
The math library is documented in section 6.7 of the Reference Manual.<a href="http://www.lua.org/manual/5.3/manual.html#6.7">[1]</a> Below is a summary of the functions and variables provided. Each is described, with an example, on this page.
|
|
<DL>
|
|
<dt><dd><pre>
|
|
math.abs
|
|
math.acos
|
|
math.asin
|
|
math.atan
|
|
math.ceil
|
|
math.cos
|
|
math.deg
|
|
math.exp
|
|
math.floor
|
|
math.fmod
|
|
math.huge
|
|
math.log
|
|
math.max
|
|
math.maxinteger
|
|
math.min
|
|
math.mininteger
|
|
math.modf
|
|
math.pi
|
|
math.rad
|
|
math.random
|
|
math.randomseed
|
|
math.sin
|
|
math.sqrt
|
|
math.tan
|
|
math.tointeger
|
|
math.type
|
|
math.ult
|
|
</pre>
|
|
</DL>
|
|
<p>
|
|
<p>
|
|
<H3>math.abs</H3>
|
|
Return the absolute, or non-negative value, of a given value.
|
|
<DL>
|
|
<dt><dd><pre>
|
|
> = math.abs(-100)
|
|
100
|
|
> = math.abs(25.67)
|
|
25.67
|
|
> = math.abs(0)
|
|
0
|
|
</pre>
|
|
</DL>
|
|
<p>
|
|
<H3>math.acos , math.asin</H3>
|
|
Return the inverse cosine and sine in radians of the given value.
|
|
<DL>
|
|
<dt><dd><pre>
|
|
> = math.acos(1)
|
|
0
|
|
> = math.acos(0)
|
|
1.5707963267949
|
|
> = math.asin(0)
|
|
0
|
|
> = math.asin(1)
|
|
1.5707963267949
|
|
</pre>
|
|
</DL>
|
|
<p>
|
|
<H3>math.atan</H3>
|
|
Return the inverse tangent in radians. We can do this by supplying y/x ourselves
|
|
or we can pass y and x to <code>math.atan</code> to do this for us.
|
|
<DL>
|
|
<dt><dd><pre>
|
|
> c, s = math.cos(0.8), math.sin(0.8)
|
|
> = math.atan(s/c)
|
|
0.8
|
|
> = math.atan(s,c)
|
|
0.8
|
|
</pre>
|
|
</DL>
|
|
<p>
|
|
Using two arguments should usually be preferred, particularly when converting rectangular co-ordinates to polar co-ordinates. It will use the sign of both arguments to place the result into the correct quadrant, and also produces correct values when one of its arguments is 0 or very close to 0.
|
|
<p>
|
|
<DL>
|
|
<dt><dd><pre>
|
|
> = math.atan(1, 0), math.atan(-1, 0), math.atan(0, 1), math.atan(0, -1)
|
|
1.5707963267949 -1.5707963267949 0 3.1415926535898
|
|
</pre>
|
|
</DL>
|
|
<p>
|
|
<H3>math.ceil , math.floor</H3>
|
|
Return the integer no greater than or no less than the given value (even for negatives).
|
|
<DL>
|
|
<dt><dd><pre>
|
|
> = math.floor(0.5)
|
|
0
|
|
> = math.ceil(0.5)
|
|
1
|
|
> = math.floor(-0.5)
|
|
-1
|
|
> = math.ceil(-0.5)
|
|
-0
|
|
</pre>
|
|
</DL>
|
|
<p>
|
|
<H3>math.cos , math.sin , math.tan</H3>
|
|
Return the cosine, sine and tangent value for a given value in radians.
|
|
<DL>
|
|
<dt><dd><pre>
|
|
> = math.cos(math.pi / 4)
|
|
0.70710678118655
|
|
> = math.sin(0.123)
|
|
0.12269009002432
|
|
> = math.tan(5/4)
|
|
3.0095696738628
|
|
> = math.tan(.77)
|
|
0.96966832796149
|
|
</pre>
|
|
</DL>
|
|
<p>
|
|
<H3>math.deg , math.rad</H3>
|
|
Convert from radians to degrees and vice versa.
|
|
<DL>
|
|
<dt><dd><pre>
|
|
> = math.deg(math.pi)
|
|
180
|
|
> = math.deg(math.pi / 2)
|
|
90
|
|
> = math.rad(180)
|
|
3.1415926535898
|
|
> = math.rad(1)
|
|
0.017453292519943
|
|
</pre>
|
|
</DL>
|
|
<p>
|
|
<p>
|
|
<H3>math.exp , math.log</H3>
|
|
<code>math.exp(myval)</code> returns <em>e</em> (the base of natural logarithms) raised to the power <code>myval</code>.
|
|
<code>math.log()</code> returns the inverse of this. <code>math.exp(1)</code> returns <em>e</em>.
|
|
<DL>
|
|
<dt><dd><pre>
|
|
> = math.exp(0)
|
|
1
|
|
> = math.exp(1)
|
|
2.718281828459
|
|
> = math.exp(27)
|
|
532048240601.8
|
|
> = math.log(532048240601)
|
|
26.999999999998
|
|
> = math.log(3)
|
|
1.0986122886681
|
|
</pre>
|
|
</DL>
|
|
<p>
|
|
<p>
|
|
<H3>math.min , math.max</H3>
|
|
Return the minimum or maximum value from a variable length list of arguments.
|
|
<DL>
|
|
<dt><dd><pre>
|
|
> = math.min(1,2)
|
|
1
|
|
> = math.min(1.2, 7, 3)
|
|
1.2
|
|
> = math.min(1.2, -7, 3)
|
|
-7
|
|
> = math.max(1.2, -7, 3)
|
|
3
|
|
> = math.max(1.2, 7, 3)
|
|
7
|
|
</pre>
|
|
</DL>
|
|
<p>
|
|
<p>
|
|
<H3>math.modf</H3>
|
|
Return the integral and fractional parts of the given number.
|
|
<DL>
|
|
<dt><dd><pre>
|
|
> = math.modf(5)
|
|
5 0
|
|
> = math.modf(5.3)
|
|
5 0.3
|
|
> = math.modf(-5.3)
|
|
-5 -0.3
|
|
</pre>
|
|
</DL>
|
|
<p>
|
|
If you want the modulus (remainder), look for the modulo <code>%</code> operator instead.<a href="http://www.lua.org/manual/5.1/manual.html#2.5.1">[2]</a>
|
|
<p>
|
|
<H3>math.sqrt</H3>
|
|
Return the square root of a given number. Only non-negative arguments are allowed.
|
|
<DL>
|
|
<dt><dd><pre>
|
|
> = math.sqrt(100)
|
|
10
|
|
> = math.sqrt(1234)
|
|
35.128336140501
|
|
> = math.sqrt(-7)
|
|
-1.#IND
|
|
</pre>
|
|
</DL>
|
|
<p>
|
|
<H3>math.random , math.randomseed</H3>
|
|
<code>math.random()</code> generates pseudo-random numbers uniformly distributed. Supplying argument alters its behaviour:
|
|
<UL>
|
|
<li> <code>math.random()</code> with no arguments generates a real number between 0 and 1.
|
|
<li> <code>math.random(upper)</code> generates integer numbers between 1 and <em>upper</em>.
|
|
<li> <code>math.random(lower, upper)</code> generates integer numbers between <em>lower</em> and <em>upper</em>.
|
|
</UL><DL>
|
|
<dt><dd><pre>
|
|
> = math.random()
|
|
0.0012512588885159
|
|
> = math.random()
|
|
0.56358531449324
|
|
> = math.random(100)
|
|
20
|
|
> = math.random(100)
|
|
81
|
|
> = math.random(70,80)
|
|
76
|
|
> = math.random(70,80)
|
|
75
|
|
</pre>
|
|
</DL>
|
|
<em>upper</em> and <em>lower</em> must be integer. In other case Lua casts <em>upper</em> into an integer, sometimes giving <code>math.floor(upper)</code> and others <code>math.ceil(upper)</code>, with unexpected results (the same for <em>lower</em>).
|
|
<p>
|
|
The <code>math.randomseed()</code> function sets a <em>seed</em> for the pseudo-random generator: Equal seeds produce equal sequences of numbers.
|
|
<DL>
|
|
<dt><dd><pre>
|
|
> math.randomseed(1234)
|
|
> = math.random(), math.random(), math.random()
|
|
0.12414929654836 0.0065004425183874 0.3894466994232
|
|
> math.randomseed(1234)
|
|
> = math.random(), math.random(), math.random()
|
|
0.12414929654836 0.0065004425183874 0.3894466994232
|
|
</pre>
|
|
</DL>
|
|
<p>
|
|
A good* 'seed' is os.time(), but wait a second before calling the function to obtain another sequence! To get nice random numbers use:
|
|
<DL>
|
|
<dt><dd><pre>
|
|
math.randomseed( os.time() )
|
|
</pre>
|
|
</DL>
|
|
If Lua could get milliseconds from <code>os.time()</code> the init could be better done. Another thing to be aware of is truncation of the seed provided. <code>math.randomseed</code> will call the underlying C function <code>srand</code> which takes an unsigned integer value. Lua will cast the value of the seed to this format. In case of an overflow the seed will actually become a bad seed, without warning <a href="http://lua-users.org/lists/lua-l/2013-05/msg00275.html">[3]</a> (note that Lua 5.1 actually casts to a signed int <a href="http://lua-users.org/lists/lua-l/2013-05/msg00290.html">[4]</a>, which was corrected in 5.2).
|
|
<p>
|
|
Nevertheless, in some cases we need a controlled sequence, like the obtained with a known seed.
|
|
<p>
|
|
But beware! The first random number you get is not really 'randomized' (at least in Windows 2K and OS X). To get better pseudo-random number just pop some random number before using them for real:
|
|
<DL>
|
|
<dt><dd><pre>
|
|
-- Initialize the pseudo random number generator
|
|
math.randomseed( os.time() )
|
|
math.random(); math.random(); math.random()
|
|
-- done. :-)
|
|
</pre>
|
|
</DL>
|
|
<p>
|
|
<em>-- This not exactly true. The first random number is as good (or bad) as the second one and the others. The goodness of the generator depends on other things. To improve somewhat the built-in generator we can use a table in the form:</em>
|
|
<DL>
|
|
<dt><dd><pre>
|
|
-- improving the built-in pseudorandom generator
|
|
do
|
|
local oldrandom = math.random
|
|
local randomtable
|
|
math.random = function ()
|
|
if randomtable == nil then
|
|
randomtable = {}
|
|
for i = 1, 97 do
|
|
randomtable[i] = oldrandom()
|
|
end
|
|
end
|
|
local x = oldrandom()
|
|
local i = 1 + math.floor(97*x)
|
|
x, randomtable[i] = randomtable[i], x
|
|
return x
|
|
end
|
|
end
|
|
</pre>
|
|
</DL>
|
|
<p>
|
|
<a href="http://lua-users.org/lists/lua-l/2007-03/msg00564.html">[5]</a> : Why math.random() might give weird results on OSX and FreeBSD?
|
|
<p>
|
|
*<em>...The problem seems to be that when the seeds differ very little the first value of generated by BSD rand() also differ very little. This difference is lost when Lua converts the integer returned by rand() into a real number, effectively preserving only the high bits in the result. When you call math.random(1,100) from Lua, the low-bit difference vanishes and you see the same integer result.</em>
|
|
<p>
|
|
<DL>
|
|
<dt><dd><pre>
|
|
-- improve seeding on these platforms by throwing away the high part of time,
|
|
-- then reversing the digits so the least significant part makes the biggest change
|
|
-- NOTE this should not be considered a replacement for using a stronger random function
|
|
-- ~ferrix
|
|
math.randomseed( tonumber(tostring(os.time()):reverse():sub(1,6)) )
|
|
</pre>
|
|
</DL>
|
|
<p>
|
|
<p>
|
|
There is also lrandom<a href="http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/#lrandom">[6]</a> A library for generating random numbers based on the Mersenne Twister.
|
|
<p>
|
|
<H3>math.huge</H3>
|
|
<p>
|
|
<code>math.huge</code> is a constant. It represents +infinity.
|
|
<p>
|
|
<DL>
|
|
<dt><dd><pre>
|
|
> = math.huge
|
|
inf
|
|
> = math.huge / 2
|
|
inf
|
|
> = -math.huge
|
|
-inf
|
|
> = math.huge/math.huge -- indeterminate
|
|
nan
|
|
> = math.huge * 0 -- indeterminate
|
|
nan
|
|
> = 1/0
|
|
inf
|
|
> = (math.huge == math.huge)
|
|
true
|
|
> = (1/0 == math.huge)
|
|
true
|
|
</pre>
|
|
</DL>
|
|
<p>
|
|
Note that some operations on <code>math.huge</code> return a special "not-a-number" value that displays as <code>nan</code>. This is a bit of a misnomer. <code>nan</code> is a number type, though it's different from other numbers:
|
|
<p>
|
|
<DL>
|
|
<dt><dd><pre>
|
|
> = type(math.huge * 0)
|
|
number
|
|
</pre>
|
|
</DL>
|
|
<p>
|
|
See also <a href="/wiki/FloatingPoint" >FloatingPoint</a>.
|
|
<p>
|
|
<H3>math.pi</H3>
|
|
<p>
|
|
This is a part of the constant Pi.
|
|
<p>
|
|
<DL>
|
|
<dt><dd><pre>
|
|
> = math.pi
|
|
3.1415926535898
|
|
</pre>
|
|
</DL>
|
|
<hr>
|
|
<a href="/wiki/RecentChanges" >RecentChanges</a> · <a href="/cgi-bin/wiki.pl?action=editprefs" >preferences</a><br>
|
|
<a href="/cgi-bin/wiki.pl?action=edit&id=MathLibraryTutorial" >edit</a> · <a href="/cgi-bin/wiki.pl?action=history&id=MathLibraryTutorial" >history</a><br>Last edited February 5, 2016 5:07 am GMT <a href="/cgi-bin/wiki.pl?action=browse&diff=1&id=MathLibraryTutorial" >(diff)</a>
|
|
</body>
|
|
</html> |