Last active
October 28, 2021 06:40
-
-
Save tuo/88ac7341de37bffbb0d091a910a593b2 to your computer and use it in GitHub Desktop.
NodeMCU implementation of Math library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- refer to https://www.esp8266.com/viewtopic.php?p=87536 | |
PI = math.pi; | |
r360 = 2*PI; -- 2*PI radians equal 360 degrees | |
r180 = PI; | |
r90 = PI/2; | |
function sin(x) -- x in radians | |
local sign = 1; | |
if x < 0 then x = -x + r180 end | |
x = x % r360; -- x < 360 | |
if x > r180 then x = r360 - x; sign = -1 end | |
if x > r90 then x = r180 - x end | |
local x2 = x*x; | |
return sign*x*(x2*(x2*(-x2+42)-840)+5040)/5040; | |
end | |
function cos(x) -- x in radians | |
return sin(x+r90); | |
end | |
function tan(x) -- x in radians | |
return sin(x)/cos(x); | |
end | |
function atan(x) -- result in radians | |
local sqrt3 = 1.732051; | |
local offset = 0; | |
local sign = 1; | |
if x <= 0 then x = -x; sign = -1 end | |
if x > 2-sqrt3 then | |
x = (x*sqrt3 - 1) / (sqrt3 + x); | |
offset = PI/6; | |
end | |
local x2 = x*x; | |
return sign*(offset + x*(x2*(x2*(-15*x2+21)-35)+105)/105); | |
end | |
function asin(x) | |
if x <= -1 or x >= 1 then error("*** Illegal argument for asin()") end | |
return atan(x/(1-x*x)^(0.5)); | |
end | |
function acos(x) | |
if x <= -1 or x >= 1 then error("*** Illegal argument for acos()") end | |
return atan((1-x*x)^(0.5)/x); | |
end | |
function toRad(x) -- degrees | |
return x*PI/180; -- radians | |
end | |
function toDeg(x) -- radians | |
return x*180/PI; -- degrees | |
end | |
function exp(x) | |
return 2.7182818284^x; | |
end | |
function ln(x) -- natural logarithm; precision approximately 5 positions after decimal dot | |
if x <= 0 then error("*** Illegal argument for ln()") end | |
local ln2 = 0.6931471; -- ln(x*2^k)=ln(x)+k*ln(2) | |
local sign = 1; | |
local k = 0; -- invariant: x*2^k is constant | |
if (x < 1) then x = 1/x; sign = -1 end | |
while (x > 1) do x = x/2; k = k+1 end -- postcondition: 0.5 < x <= 1 | |
x = 1 - x; -- 0 <= x < 0.5 for fast convergence. First 6 series expansion terms: | |
local sum = x*(x*(x*(x*(x*(10*x+12)+15)+20)+30)+60)/60; -- ln(1-x)=-(sum(x^n/n),n:0..inf,-1<=x<1. | |
return sign * (k*ln2 - sum); | |
end | |
function truncate(x) -- integer part of x | |
return x > 0 and math.floor(x) or math.ceil(x) | |
end | |
function round(x) -- x rounded to nearest integer | |
return x >= 0 and math.ceil(x-0.5) or math.floor(x+0.5) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment