views:

71

answers:

1

Ok, first up, this is NOT for a class, test, or other student type activity.

I'm a scripter for a game, and am trying to implement the math library for all to use, and unfortunately, all I have available to me is very basic lua. The implemented version cannot be changed, and does not include any libraries. For those wondering, its for scripting in Fold.It.

Here's what I have...

math={}
math.fact = function(b) if(b==1)or(b==0) then return 1 end e=1 for c=b,1,-1 do e=e*c end return e end
math.pow = function(b,p) e=b if(p==0) then return 1 end if(p<0) then p=p*(-1) end for c=p,2,-1 do e=e*b end return e end
math.cos = function(b,p) e=0 p=p or 10 for i=1,p do e=e+(math.pow(-1,i)*math.pow(b,2*i)/math.fact(2*i)) end return e end

To clarify above, math.fact returns factorial, which is returning accurate to about 10 points of precision, and is a new function I've done to aid in cosine calculation.

The math.pow is also a new function to handle returning powers, also working as expected.

The issue is with the cosine function. Its returning unexpected values. Here's an easier to digest version (I've been writing my library stuff ultra lean)...

function math.cos(value,precision) 
    result=0 
    precision=precision or 10 
    for i=1,precision do 
        result=result+(math.pow(-1,i)*math.pow(value,2*i)/math.fact(2*i)) 
    end 
    return e 
end

The problem is, with those functions, for print(math.cos(90)) it returns 4.77135... when I'm expecting -0.44807... (based on calc in scientific mode, or using an online tool to cos(90)).

I'm also having issues with sin and tan, however they are similarly written to cos, which seems to have been done in many languages. If I can figure out what I'm doing wrong, I can get them all fixed.

EDIT: Corrected typo

+3  A: 

First, your lua doesn't run. Second, you need to make your variables local. Third, cosine starts with a one.

The problem is because the Taylor series you are using only converges on the correct values of cosine close to zero. You would have to use a far more terms of the series to get it to handle 90 correctly. You can fix this for your implementation two ways:

Add a pi constant. Then use a while loop to adjust the value such that abs(value) < 2*pi:

math.pi = 3.14159265358
while value > math.pi*2 do 
  value = value - math.pi * 2 
end
while value < -math.pi*2 do
  value = value + math.pi * 2
end

Or - find or implement a version of fmod in lua.

Here is the corrected code (you can minify it):

math={}
math.fact = function(b)
    if(b==1)or(b==0) then
        return 1
    end
    local e=1
    for c=b,1,-1 do
        e=e*c
    end
    return e
end

math.pow = function(b,p)
    local e=b
    if(p==0) then
        return 1
    end
    if(p<0) then
        p=p*(-1)
    end
    for c=p,2,-1 do
        e=e*b
    end
    return e
end
math.cos = function(b,p)
    local e=1 
    b = math.correctRadians(b) 
    p=p or 10
    for i=1,p do
        e=e+(math.pow(-1,i)*math.pow(b,2*i)/math.fact(2*i))
    end
    return e
end

math.pi = 3.1415926545358
math.correctRadians = function( value )
    while value > math.pi*2 do
        value = value - math.pi * 2
    end           
    while value < -math.pi*2 do
        value = value + math.pi * 2
    end 
    return value
end 

interactive lua run:

imac:~ root$ lua -i temp.lua 
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> print( math.cos( 90 ) )
-0.44807359244883
> 
Jonathan Swinney
Ooops, I had started typing the easy to read version in the source, before I copied, and forgot to fix it. Should have been "math.cos = function(b,p) e=0"...
FWishbringer
Ok, went over it, and its working, and returning correct values. I haven't had to touch math this in depth since college, and have found it to NOT be like riding a bicycle. Thank you very much for your help. Now, time to use this as a basis for sin and the rest.
FWishbringer