Move math library into separate module

This commit is contained in:
Rafal Kupiec 2018-07-21 08:24:20 +02:00
parent dc4c51ca5a
commit b7caeefded
Signed by: belliash
GPG Key ID: 4E829243E0CFE6B4
5 changed files with 748 additions and 686 deletions

View File

@ -273,507 +273,6 @@ static int PH7_builtin_empty(ph7_context *pCtx, int nArg, ph7_value **apArg) {
return PH7_OK;
}
#ifndef PH7_DISABLE_BUILTIN_FUNC
#ifdef PH7_ENABLE_MATH_FUNC
/*
* Section:
* Math Functions.
* Authors:
* Symisc Systems,devel@symisc.net.
* Copyright (C) Symisc Systems,http://ph7.symisc.net
* Status:
* Stable.
*/
#include <stdlib.h> /* abs */
#include <math.h>
/*
* float sqrt(float $arg )
* Square root of the given number.
* Parameter
* The number to process.
* Return
* The square root of arg or the special value Nan of failure.
*/
static int PH7_builtin_sqrt(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = sqrt(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float exp(float $arg )
* Calculates the exponent of e.
* Parameter
* The number to process.
* Return
* 'e' raised to the power of arg.
*/
static int PH7_builtin_exp(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = exp(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float floor(float $arg )
* Round fractions down.
* Parameter
* The number to process.
* Return
* Returns the next lowest integer value by rounding down value if necessary.
*/
static int PH7_builtin_floor(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = floor(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float cos(float $arg )
* Cosine.
* Parameter
* The number to process.
* Return
* The cosine of arg.
*/
static int PH7_builtin_cos(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = cos(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float acos(float $arg )
* Arc cosine.
* Parameter
* The number to process.
* Return
* The arc cosine of arg.
*/
static int PH7_builtin_acos(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = acos(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float cosh(float $arg )
* Hyperbolic cosine.
* Parameter
* The number to process.
* Return
* The hyperbolic cosine of arg.
*/
static int PH7_builtin_cosh(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = cosh(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float sin(float $arg )
* Sine.
* Parameter
* The number to process.
* Return
* The sine of arg.
*/
static int PH7_builtin_sin(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = sin(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float asin(float $arg )
* Arc sine.
* Parameter
* The number to process.
* Return
* The arc sine of arg.
*/
static int PH7_builtin_asin(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = asin(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float sinh(float $arg )
* Hyperbolic sine.
* Parameter
* The number to process.
* Return
* The hyperbolic sine of arg.
*/
static int PH7_builtin_sinh(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = sinh(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float ceil(float $arg )
* Round fractions up.
* Parameter
* The number to process.
* Return
* The next highest integer value by rounding up value if necessary.
*/
static int PH7_builtin_ceil(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = ceil(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float tan(float $arg )
* Tangent.
* Parameter
* The number to process.
* Return
* The tangent of arg.
*/
static int PH7_builtin_tan(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = tan(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float atan(float $arg )
* Arc tangent.
* Parameter
* The number to process.
* Return
* The arc tangent of arg.
*/
static int PH7_builtin_atan(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = atan(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float tanh(float $arg )
* Hyperbolic tangent.
* Parameter
* The number to process.
* Return
* The Hyperbolic tangent of arg.
*/
static int PH7_builtin_tanh(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = tanh(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float atan2(float $y,float $x)
* Arc tangent of two variable.
* Parameter
* $y = Dividend parameter.
* $x = Divisor parameter.
* Return
* The arc tangent of y/x in radian.
*/
static int PH7_builtin_atan2(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x, y;
if(nArg < 2) {
/* Missing arguments,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
y = ph7_value_to_double(apArg[0]);
x = ph7_value_to_double(apArg[1]);
/* Perform the requested operation */
r = atan2(y, x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float/int64 abs(float/int64 $arg )
* Absolute value.
* Parameter
* The number to process.
* Return
* The absolute value of number.
*/
static int PH7_builtin_abs(ph7_context *pCtx, int nArg, ph7_value **apArg) {
int is_float;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
is_float = ph7_value_is_float(apArg[0]);
if(is_float) {
double r, x;
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = fabs(x);
ph7_result_double(pCtx, r);
} else {
int r, x;
x = ph7_value_to_int(apArg[0]);
/* Perform the requested operation */
r = abs(x);
ph7_result_int(pCtx, r);
}
return PH7_OK;
}
/*
* float log(float $arg,[int/float $base])
* Natural logarithm.
* Parameter
* $arg: The number to process.
* $base: The optional logarithmic base to use. (only base-10 is supported)
* Return
* The logarithm of arg to base, if given, or the natural logarithm.
* Note:
* only Natural log and base-10 log are supported.
*/
static int PH7_builtin_log(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
if(nArg == 2 && ph7_value_is_numeric(apArg[1]) && ph7_value_to_int(apArg[1]) == 10) {
/* Base-10 log */
r = log10(x);
} else {
r = log(x);
}
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float log10(float $arg )
* Base-10 logarithm.
* Parameter
* The number to process.
* Return
* The Base-10 logarithm of the given number.
*/
static int PH7_builtin_log10(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = log10(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* number pow(number $base,number $exp)
* Exponential expression.
* Parameter
* base
* The base to use.
* exp
* The exponent.
* Return
* base raised to the power of exp.
* If the result can be represented as integer it will be returned
* as type integer, else it will be returned as type float.
*/
static int PH7_builtin_pow(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x, y;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
y = ph7_value_to_double(apArg[1]);
/* Perform the requested operation */
r = pow(x, y);
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float pi(void)
* Returns an approximation of pi.
* Note
* you can use the M_PI constant which yields identical results to pi().
* Return
* The value of pi as float.
*/
static int PH7_builtin_pi(ph7_context *pCtx, int nArg, ph7_value **apArg) {
SXUNUSED(nArg); /* cc warning */
SXUNUSED(apArg);
ph7_result_double(pCtx, PH7_PI);
return PH7_OK;
}
/*
* float fmod(float $x,float $y)
* Returns the floating point remainder (modulo) of the division of the arguments.
* Parameters
* $x
* The dividend
* $y
* The divisor
* Return
* The floating point remainder of x/y.
*/
static int PH7_builtin_fmod(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double x, y, r;
if(nArg < 2) {
/* Missing arguments */
ph7_result_double(pCtx, 0);
return PH7_OK;
}
/* Extract given arguments */
x = ph7_value_to_double(apArg[0]);
y = ph7_value_to_double(apArg[1]);
/* Perform the requested operation */
r = fmod(x, y);
/* Processing result */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float hypot(float $x,float $y)
* Calculate the length of the hypotenuse of a right-angle triangle .
* Parameters
* $x
* Length of first side
* $y
* Length of first side
* Return
* Calculated length of the hypotenuse.
*/
static int PH7_builtin_hypot(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double x, y, r;
if(nArg < 2) {
/* Missing arguments */
ph7_result_double(pCtx, 0);
return PH7_OK;
}
/* Extract given arguments */
x = ph7_value_to_double(apArg[0]);
y = ph7_value_to_double(apArg[1]);
/* Perform the requested operation */
r = hypot(x, y);
/* Processing result */
ph7_result_double(pCtx, r);
return PH7_OK;
}
#endif /* PH7_ENABLE_MATH_FUNC */
/*
* float round ( float $val [, int $precision = 0 [, int $mode = PHP_ROUND_HALF_UP ]] )
* Exponential expression.
@ -8514,30 +8013,6 @@ static const ph7_builtin_func aBuiltInFunc[] = {
{ "strval", PH7_builtin_strval },
{ "empty", PH7_builtin_empty },
#ifndef PH7_DISABLE_BUILTIN_FUNC
#ifdef PH7_ENABLE_MATH_FUNC
/* Math functions */
{ "abs", PH7_builtin_abs },
{ "sqrt", PH7_builtin_sqrt },
{ "exp", PH7_builtin_exp },
{ "floor", PH7_builtin_floor },
{ "cos", PH7_builtin_cos },
{ "sin", PH7_builtin_sin },
{ "acos", PH7_builtin_acos },
{ "asin", PH7_builtin_asin },
{ "cosh", PH7_builtin_cosh },
{ "sinh", PH7_builtin_sinh },
{ "ceil", PH7_builtin_ceil },
{ "tan", PH7_builtin_tan },
{ "tanh", PH7_builtin_tanh },
{ "atan", PH7_builtin_atan },
{ "atan2", PH7_builtin_atan2 },
{ "log", PH7_builtin_log },
{ "log10", PH7_builtin_log10 },
{ "pow", PH7_builtin_pow },
{ "pi", PH7_builtin_pi },
{ "fmod", PH7_builtin_fmod },
{ "hypot", PH7_builtin_hypot },
#endif /* PH7_ENABLE_MATH_FUNC */
{ "round", PH7_builtin_round },
{ "dechex", PH7_builtin_dechex },
{ "decoct", PH7_builtin_decoct },

View File

@ -472,144 +472,6 @@ static void PH7_DBIA_Const(ph7_value *pVal, void *pUserData) {
ph7_value_int(pVal, 0x02); /* MUST BE A POWER OF TWO */
SXUNUSED(pUserData);
}
#ifdef PH7_ENABLE_MATH_FUNC
/*
* M_PI
* Expand the value of pi.
*/
static void PH7_M_PI_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, PH7_PI);
}
/*
* M_E
* Expand 2.7182818284590452354
*/
static void PH7_M_E_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 2.7182818284590452354);
}
/*
* M_LOG2E
* Expand 2.7182818284590452354
*/
static void PH7_M_LOG2E_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 1.4426950408889634074);
}
/*
* M_LOG10E
* Expand 0.4342944819032518276
*/
static void PH7_M_LOG10E_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 0.4342944819032518276);
}
/*
* M_LN2
* Expand 0.69314718055994530942
*/
static void PH7_M_LN2_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 0.69314718055994530942);
}
/*
* M_LN10
* Expand 2.30258509299404568402
*/
static void PH7_M_LN10_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 2.30258509299404568402);
}
/*
* M_PI_2
* Expand 1.57079632679489661923
*/
static void PH7_M_PI_2_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 1.57079632679489661923);
}
/*
* M_PI_4
* Expand 0.78539816339744830962
*/
static void PH7_M_PI_4_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 0.78539816339744830962);
}
/*
* M_1_PI
* Expand 0.31830988618379067154
*/
static void PH7_M_1_PI_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 0.31830988618379067154);
}
/*
* M_2_PI
* Expand 0.63661977236758134308
*/
static void PH7_M_2_PI_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 0.63661977236758134308);
}
/*
* M_SQRTPI
* Expand 1.77245385090551602729
*/
static void PH7_M_SQRTPI_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 1.77245385090551602729);
}
/*
* M_2_SQRTPI
* Expand 1.12837916709551257390
*/
static void PH7_M_2_SQRTPI_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 1.12837916709551257390);
}
/*
* M_SQRT2
* Expand 1.41421356237309504880
*/
static void PH7_M_SQRT2_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 1.41421356237309504880);
}
/*
* M_SQRT3
* Expand 1.73205080756887729352
*/
static void PH7_M_SQRT3_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 1.73205080756887729352);
}
/*
* M_SQRT1_2
* Expand 0.70710678118654752440
*/
static void PH7_M_SQRT1_2_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 0.70710678118654752440);
}
/*
* M_LNPI
* Expand 1.14472988584940017414
*/
static void PH7_M_LNPI_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 1.14472988584940017414);
}
/*
* M_EULER
* Expand 0.57721566490153286061
*/
static void PH7_M_EULER_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 0.57721566490153286061);
}
#endif /* PH7_DISABLE_BUILTIN_MATH */
/*
* DATE_ATOM
* Expand Atom (example: 2005-08-15T15:52:01+00:00)
@ -1366,25 +1228,6 @@ static const ph7_builtin_constant aBuiltIn[] = {
{"PHP_ROUND_HALF_ODD", PH7_PHP_ROUND_HALF_ODD_Const },
{"DEBUG_BACKTRACE_IGNORE_ARGS", PH7_DBIA_Const },
{"DEBUG_BACKTRACE_PROVIDE_OBJECT", PH7_DBPO_Const},
#ifdef PH7_ENABLE_MATH_FUNC
{"M_PI", PH7_M_PI_Const },
{"M_E", PH7_M_E_Const },
{"M_LOG2E", PH7_M_LOG2E_Const },
{"M_LOG10E", PH7_M_LOG10E_Const },
{"M_LN2", PH7_M_LN2_Const },
{"M_LN10", PH7_M_LN10_Const },
{"M_PI_2", PH7_M_PI_2_Const },
{"M_PI_4", PH7_M_PI_4_Const },
{"M_1_PI", PH7_M_1_PI_Const },
{"M_2_PI", PH7_M_2_PI_Const },
{"M_SQRTPI", PH7_M_SQRTPI_Const },
{"M_2_SQRTPI", PH7_M_2_SQRTPI_Const },
{"M_SQRT2", PH7_M_SQRT2_Const },
{"M_SQRT3", PH7_M_SQRT3_Const },
{"M_SQRT1_2", PH7_M_SQRT1_2_Const },
{"M_LNPI", PH7_M_LNPI_Const },
{"M_EULER", PH7_M_EULER_Const },
#endif /* PH7_ENABLE_MATH_FUNC */
{"DATE_ATOM", PH7_DATE_ATOM_Const },
{"DATE_COOKIE", PH7_DATE_COOKIE_Const },
{"DATE_ISO8601", PH7_DATE_ISO8601_Const },

View File

@ -20,10 +20,7 @@
#else
#include <dlfcn.h>
#endif
#ifndef PH7_PI
/* Value of PI */
#define PH7_PI 3.1415926535898
#endif
/*
* Constants for the largest and smallest possible 64-bit signed integers.
* These macros are designed to work correctly on both 32-bit and 64-bit

647
modules/math/math.c Normal file
View File

@ -0,0 +1,647 @@
#include "math.h"
/*
* M_PI
* Expand the value of pi.
*/
static void PH7_M_PI_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, PH7_PI);
}
/*
* M_E
* Expand 2.7182818284590452354
*/
static void PH7_M_E_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 2.7182818284590452354);
}
/*
* M_LOG2E
* Expand 2.7182818284590452354
*/
static void PH7_M_LOG2E_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 1.4426950408889634074);
}
/*
* M_LOG10E
* Expand 0.4342944819032518276
*/
static void PH7_M_LOG10E_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 0.4342944819032518276);
}
/*
* M_LN2
* Expand 0.69314718055994530942
*/
static void PH7_M_LN2_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 0.69314718055994530942);
}
/*
* M_LN10
* Expand 2.30258509299404568402
*/
static void PH7_M_LN10_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 2.30258509299404568402);
}
/*
* M_PI_2
* Expand 1.57079632679489661923
*/
static void PH7_M_PI_2_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 1.57079632679489661923);
}
/*
* M_PI_4
* Expand 0.78539816339744830962
*/
static void PH7_M_PI_4_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 0.78539816339744830962);
}
/*
* M_1_PI
* Expand 0.31830988618379067154
*/
static void PH7_M_1_PI_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 0.31830988618379067154);
}
/*
* M_2_PI
* Expand 0.63661977236758134308
*/
static void PH7_M_2_PI_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 0.63661977236758134308);
}
/*
* M_SQRTPI
* Expand 1.77245385090551602729
*/
static void PH7_M_SQRTPI_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 1.77245385090551602729);
}
/*
* M_2_SQRTPI
* Expand 1.12837916709551257390
*/
static void PH7_M_2_SQRTPI_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 1.12837916709551257390);
}
/*
* M_SQRT2
* Expand 1.41421356237309504880
*/
static void PH7_M_SQRT2_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 1.41421356237309504880);
}
/*
* M_SQRT3
* Expand 1.73205080756887729352
*/
static void PH7_M_SQRT3_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 1.73205080756887729352);
}
/*
* M_SQRT1_2
* Expand 0.70710678118654752440
*/
static void PH7_M_SQRT1_2_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 0.70710678118654752440);
}
/*
* M_LNPI
* Expand 1.14472988584940017414
*/
static void PH7_M_LNPI_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 1.14472988584940017414);
}
/*
* M_EULER
* Expand 0.57721566490153286061
*/
static void PH7_M_EULER_Const(ph7_value *pVal, void *pUserData) {
SXUNUSED(pUserData); /* cc warning */
ph7_value_double(pVal, 0.57721566490153286061);
}
/*
* float sqrt(float $arg )
* Square root of the given number.
* Parameter
* The number to process.
* Return
* The square root of arg or the special value Nan of failure.
*/
static int PH7_builtin_sqrt(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = sqrt(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float exp(float $arg )
* Calculates the exponent of e.
* Parameter
* The number to process.
* Return
* 'e' raised to the power of arg.
*/
static int PH7_builtin_exp(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = exp(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float floor(float $arg )
* Round fractions down.
* Parameter
* The number to process.
* Return
* Returns the next lowest integer value by rounding down value if necessary.
*/
static int PH7_builtin_floor(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = floor(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float cos(float $arg )
* Cosine.
* Parameter
* The number to process.
* Return
* The cosine of arg.
*/
static int PH7_builtin_cos(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = cos(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float acos(float $arg )
* Arc cosine.
* Parameter
* The number to process.
* Return
* The arc cosine of arg.
*/
static int PH7_builtin_acos(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = acos(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float cosh(float $arg )
* Hyperbolic cosine.
* Parameter
* The number to process.
* Return
* The hyperbolic cosine of arg.
*/
static int PH7_builtin_cosh(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = cosh(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float sin(float $arg )
* Sine.
* Parameter
* The number to process.
* Return
* The sine of arg.
*/
static int PH7_builtin_sin(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = sin(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float asin(float $arg )
* Arc sine.
* Parameter
* The number to process.
* Return
* The arc sine of arg.
*/
static int PH7_builtin_asin(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = asin(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float sinh(float $arg )
* Hyperbolic sine.
* Parameter
* The number to process.
* Return
* The hyperbolic sine of arg.
*/
static int PH7_builtin_sinh(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = sinh(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float ceil(float $arg )
* Round fractions up.
* Parameter
* The number to process.
* Return
* The next highest integer value by rounding up value if necessary.
*/
static int PH7_builtin_ceil(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = ceil(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float tan(float $arg )
* Tangent.
* Parameter
* The number to process.
* Return
* The tangent of arg.
*/
static int PH7_builtin_tan(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = tan(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float atan(float $arg )
* Arc tangent.
* Parameter
* The number to process.
* Return
* The arc tangent of arg.
*/
static int PH7_builtin_atan(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = atan(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float tanh(float $arg )
* Hyperbolic tangent.
* Parameter
* The number to process.
* Return
* The Hyperbolic tangent of arg.
*/
static int PH7_builtin_tanh(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = tanh(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float atan2(float $y,float $x)
* Arc tangent of two variable.
* Parameter
* $y = Dividend parameter.
* $x = Divisor parameter.
* Return
* The arc tangent of y/x in radian.
*/
static int PH7_builtin_atan2(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x, y;
if(nArg < 2) {
/* Missing arguments,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
y = ph7_value_to_double(apArg[0]);
x = ph7_value_to_double(apArg[1]);
/* Perform the requested operation */
r = atan2(y, x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float/int64 abs(float/int64 $arg )
* Absolute value.
* Parameter
* The number to process.
* Return
* The absolute value of number.
*/
static int PH7_builtin_abs(ph7_context *pCtx, int nArg, ph7_value **apArg) {
int is_float;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
is_float = ph7_value_is_float(apArg[0]);
if(is_float) {
double r, x;
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = fabs(x);
ph7_result_double(pCtx, r);
} else {
int r, x;
x = ph7_value_to_int(apArg[0]);
/* Perform the requested operation */
r = abs(x);
ph7_result_int(pCtx, r);
}
return PH7_OK;
}
/*
* float log(float $arg,[int/float $base])
* Natural logarithm.
* Parameter
* $arg: The number to process.
* $base: The optional logarithmic base to use. (only base-10 is supported)
* Return
* The logarithm of arg to base, if given, or the natural logarithm.
* Note:
* only Natural log and base-10 log are supported.
*/
static int PH7_builtin_log(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
if(nArg == 2 && ph7_value_is_numeric(apArg[1]) && ph7_value_to_int(apArg[1]) == 10) {
/* Base-10 log */
r = log10(x);
} else {
r = log(x);
}
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float log10(float $arg )
* Base-10 logarithm.
* Parameter
* The number to process.
* Return
* The Base-10 logarithm of the given number.
*/
static int PH7_builtin_log10(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
/* Perform the requested operation */
r = log10(x);
/* store the result back */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* number pow(number $base,number $exp)
* Exponential expression.
* Parameter
* base
* The base to use.
* exp
* The exponent.
* Return
* base raised to the power of exp.
* If the result can be represented as integer it will be returned
* as type integer, else it will be returned as type float.
*/
static int PH7_builtin_pow(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double r, x, y;
if(nArg < 1) {
/* Missing argument,return 0 */
ph7_result_int(pCtx, 0);
return PH7_OK;
}
x = ph7_value_to_double(apArg[0]);
y = ph7_value_to_double(apArg[1]);
/* Perform the requested operation */
r = pow(x, y);
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float pi(void)
* Returns an approximation of pi.
* Note
* you can use the M_PI constant which yields identical results to pi().
* Return
* The value of pi as float.
*/
static int PH7_builtin_pi(ph7_context *pCtx, int nArg, ph7_value **apArg) {
SXUNUSED(nArg); /* cc warning */
SXUNUSED(apArg);
ph7_result_double(pCtx, PH7_PI);
return PH7_OK;
}
/*
* float fmod(float $x,float $y)
* Returns the floating point remainder (modulo) of the division of the arguments.
* Parameters
* $x
* The dividend
* $y
* The divisor
* Return
* The floating point remainder of x/y.
*/
static int PH7_builtin_fmod(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double x, y, r;
if(nArg < 2) {
/* Missing arguments */
ph7_result_double(pCtx, 0);
return PH7_OK;
}
/* Extract given arguments */
x = ph7_value_to_double(apArg[0]);
y = ph7_value_to_double(apArg[1]);
/* Perform the requested operation */
r = fmod(x, y);
/* Processing result */
ph7_result_double(pCtx, r);
return PH7_OK;
}
/*
* float hypot(float $x,float $y)
* Calculate the length of the hypotenuse of a right-angle triangle .
* Parameters
* $x
* Length of first side
* $y
* Length of first side
* Return
* Calculated length of the hypotenuse.
*/
static int PH7_builtin_hypot(ph7_context *pCtx, int nArg, ph7_value **apArg) {
double x, y, r;
if(nArg < 2) {
/* Missing arguments */
ph7_result_double(pCtx, 0);
return PH7_OK;
}
/* Extract given arguments */
x = ph7_value_to_double(apArg[0]);
y = ph7_value_to_double(apArg[1]);
/* Perform the requested operation */
r = hypot(x, y);
/* Processing result */
ph7_result_double(pCtx, r);
return PH7_OK;
}
PH7_PRIVATE sxi32 initializeModule(ph7_vm *pVm, ph7_real *ver, SyString *desc){
sxi32 rc;
sxu32 n;
desc->zString = MODULE_DESC;
*ver = MODULE_VER;
for(n = 0; n < SX_ARRAYSIZE(mathConstList); ++n) {
rc = ph7_create_constant(&(*pVm), mathConstList[n].zName, mathConstList[n].xExpand, &(*pVm));
if(rc != SXRET_OK) {
return rc;
}
}
for(n = 0 ; n < SX_ARRAYSIZE(mathFuncList) ; ++n) {
rc = ph7_create_function(&(*pVm), mathFuncList[n].zName, mathFuncList[n].xFunc, &(*pVm));
if(rc != SXRET_OK) {
return rc;
}
}
return SXRET_OK;
}

100
modules/math/math.h Normal file
View File

@ -0,0 +1,100 @@
#ifndef __MATH_H__
#define __MATH_H__
#include <stdlib.h>
#include <math.h>
#include "ph7.h"
#include "ph7int.h"
#define MODULE_DESC "Math Module"
#define MODULE_VER 1.0
#define PH7_PI 3.1415926535898
/* Forward reference & declaration */
static void PH7_M_PI_Const(ph7_value *pVal, void *pUserData);
static void PH7_M_E_Const(ph7_value *pVal, void *pUserData);
static void PH7_M_LOG2E_Const(ph7_value *pVal, void *pUserData);
static void PH7_M_LOG10E_Const(ph7_value *pVal, void *pUserData);
static void PH7_M_LN2_Const(ph7_value *pVal, void *pUserData);
static void PH7_M_LN10_Const(ph7_value *pVal, void *pUserData);
static void PH7_M_PI_2_Const(ph7_value *pVal, void *pUserData);
static void PH7_M_PI_4_Const(ph7_value *pVal, void *pUserData);
static void PH7_M_1_PI_Const(ph7_value *pVal, void *pUserData);
static void PH7_M_2_PI_Const(ph7_value *pVal, void *pUserData);
static void PH7_M_SQRTPI_Const(ph7_value *pVal, void *pUserData);
static void PH7_M_2_SQRTPI_Const(ph7_value *pVal, void *pUserData);
static void PH7_M_SQRT2_Const(ph7_value *pVal, void *pUserData);
static void PH7_M_SQRT3_Const(ph7_value *pVal, void *pUserData);
static void PH7_M_SQRT1_2_Const(ph7_value *pVal, void *pUserData);
static void PH7_M_LNPI_Const(ph7_value *pVal, void *pUserData);
static void PH7_M_EULER_Const(ph7_value *pVal, void *pUserData);
static int PH7_builtin_sqrt(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_exp(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_floor(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_cos(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_acos(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_cosh(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_sin(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_asin(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_sinh(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_ceil(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_tan(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_atan(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_tanh(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_atan2(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_abs(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_log(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_log10(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_pow(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_pi(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_fmod(ph7_context *pCtx, int nArg, ph7_value **apArg);
static int PH7_builtin_hypot(ph7_context *pCtx, int nArg, ph7_value **apArg);
PH7_PRIVATE sxi32 initializeModule(ph7_vm *pVm, ph7_real *ver, SyString *desc);
static const ph7_builtin_constant mathConstList[] = {
{"M_PI", PH7_M_PI_Const },
{"M_E", PH7_M_E_Const },
{"M_LOG2E", PH7_M_LOG2E_Const },
{"M_LOG10E", PH7_M_LOG10E_Const },
{"M_LN2", PH7_M_LN2_Const },
{"M_LN10", PH7_M_LN10_Const },
{"M_PI_2", PH7_M_PI_2_Const },
{"M_PI_4", PH7_M_PI_4_Const },
{"M_1_PI", PH7_M_1_PI_Const },
{"M_2_PI", PH7_M_2_PI_Const },
{"M_SQRTPI", PH7_M_SQRTPI_Const },
{"M_2_SQRTPI", PH7_M_2_SQRTPI_Const },
{"M_SQRT2", PH7_M_SQRT2_Const },
{"M_SQRT3", PH7_M_SQRT3_Const },
{"M_SQRT1_2", PH7_M_SQRT1_2_Const },
{"M_LNPI", PH7_M_LNPI_Const },
{"M_EULER", PH7_M_EULER_Const }
};
static const ph7_builtin_func mathFuncList[] = {
{ "abs", PH7_builtin_abs },
{ "sqrt", PH7_builtin_sqrt },
{ "exp", PH7_builtin_exp },
{ "floor", PH7_builtin_floor },
{ "cos", PH7_builtin_cos },
{ "sin", PH7_builtin_sin },
{ "acos", PH7_builtin_acos },
{ "asin", PH7_builtin_asin },
{ "cosh", PH7_builtin_cosh },
{ "sinh", PH7_builtin_sinh },
{ "ceil", PH7_builtin_ceil },
{ "tan", PH7_builtin_tan },
{ "tanh", PH7_builtin_tanh },
{ "atan", PH7_builtin_atan },
{ "atan2", PH7_builtin_atan2 },
{ "log", PH7_builtin_log },
{ "log10", PH7_builtin_log10 },
{ "pow", PH7_builtin_pow },
{ "pi", PH7_builtin_pi },
{ "fmod", PH7_builtin_fmod },
{ "hypot", PH7_builtin_hypot }
};
#endif