Math Library Tutorial |
|
math.abs math.acos math.asin math.atan math.atan2 math.ceil math.cos math.cosh math.deg math.exp math.floor math.fmod math.frexp math.huge math.ldexp math.log math.log10 math.max math.min math.modf math.pi math.pow math.rad math.random math.randomseed math.sin math.sinh math.sqrt math.tanh math.tan
> = math.abs(-100) 100 > = math.abs(25.67) 25.67 > = math.abs(0) 0
> = math.acos(1) 0 > = math.acos(0) 1.5707963267949 > = math.asin(0) 0 > = math.asin(1) 1.5707963267949
math.atan
or we can pass y and x to math.atan2
to do this
for us.
> c, s = math.cos(0.8), math.sin(0.8) > = math.atan(s/c) 0.8 > = math.atan2(s,c) 0.8
math.atan2
should usually be preferred, particularly when converting rectangular co-ordinates to polar co-ordinates. math.atan2
uses 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.
> = math.atan2(1, 0), math.atan2(-1, 0), math.atan2(0, 1), math.atan2(0, -1) 1.5707963267949 -1.5707963267949 0 3.1415926535898
> = math.floor(0.5) 0 > = math.ceil(0.5) 1
> = math.cos(math.pi / 4) 0.70710678118655 > = math.sin(0.123) 0.12269009002432 > = math.tan(5/4) 3.0095696738628 > = math.tan(.77) 0.96966832796149
> = math.sinh(1) 1.1752011936438
> = math.deg(math.pi) 180 > = math.deg(math.pi / 2) 90 > = math.rad(180) 3.1415926535898 > = math.rad(1) 0.017453292519943
math.exp(myval)
returns e (the base of natural logarithms) raised to the power myval
.
math.log()
returns the inverse of this. math.exp(1)
returns e.
> = math.exp(0) 1 > = math.exp(1) 2.718281828459 > = math.exp(27) 532048240601.8 > = math.log(532048240601) 26.999999999998 > = math.log(3) 1.0986122886681
> = math.log10(100) 2 > = math.log10(256) 2.4082399653118 > = math.log10(-1) -- can return -1.#INF on some Windows installs nan
math.pow()
raises the first parameter to the power of the second parameter and returns the result. The binary ^
operator performs the same job as math.pow()
, i.e. math.pow(x,y) == x^y.
> = math.pow(100,0) 1 > = math.pow(7,2) 49 > = math.pow(2,8) 256 > = math.pow(3,2.7) 19.419023519771 > = 5 ^ 2 25 > = 2^8 256
> = 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
> = math.modf(5) 5 0 > = math.modf(5.3) 5 0.3 > = math.modf(-5.3) -5 -0.3
If you want the modulus (remainder), look for the modulo %
operator instead.[3]
> = math.sqrt(100) 10 > = math.sqrt(1234) 35.128336140501 > = math.sqrt(-7) -1.#IND
math.random()
generates pseudo-random numbers uniformly distributed. Supplying argument alters its behaviour:
math.random()
with no arguments generates a real number between 0 and 1.
math.random(upper)
generates integer numbers between 1 and upper.
math.random(lower, upper)
generates integer numbers between lower and upper.
> = 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
math.floor(upper)
and others math.ceil(upper)
, with unexpected results (the same for lower).
The math.randomseed()
function sets a seed for the pseudo-random generator: Equal seeds produce equal sequences of numbers.
> 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
A good* 'seed' is os.time(), but wait a second before calling the function to obtain another sequence! To get nice random numbers use:
math.randomseed( os.time() )
os.time()
the init could be better done. Another thing to be aware of is truncation of the seed provided. math.randomseed
will call the underlying C function srand
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 [4] (note that Lua 5.1 actually casts to a signed int [5], which was corrected in 5.2).
Nevertheless, in some cases we need a controlled sequence, like the obtained with a known seed.
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:
-- Initialize the pseudo random number generator math.randomseed( os.time() ) math.random(); math.random(); math.random() -- done. :-)
-- 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:
-- 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
[6] : Why math.random() might give weird results on OSX and FreeBSD?
*...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.
-- 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)) )
There is also lrandom[7] A library for generating random numbers based on the Mersenne Twister.
math.frexp()
function is used to split the number value into a normalized fraction and an exponent. Two values are returned: the first is a value always in the range 1/2 (inclusive) to 1 (exclusive) and the second is an exponent.The number value will be returned in the operation:
> = normalized_fraction * 2 ^ exponent
math.ldexp()
function takes a normalised number and returns the floating point representation. This is the value multiplied by 2 to the power of the exponent, i.e.:
> = math.ldexp(x, exp) == x * 2 ^ exp true
> = math.frexp(2) 0.5 2 > = math.frexp(3) 0.75 2 > = math.frexp(128) 0.5 8 > = math.frexp(3.1415927) 0.785398175 2 > = math.ldexp(0.785,2) 3.14 > = math.ldexp(0.5,8) 128
math.huge
is a constant. It represents +infinity.
> = 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
Note that some operations on math.huge
return a special "not-a-number" value that displays as nan
. This is a bit of a misnomer. nan
is a number type, though it's different from other numbers:
> = type(math.huge * 0) number
See also FloatingPoint.
This is a part of the constant Pi.
> = math.pi 3.1415926535898