📄 emathfun.c
字号:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.22 06/15/04 */ /* */ /* EXTENDED MATH FUNCTIONS MODULE */ /*******************************************************//*************************************************************//* Purpose: Contains the code for numerous extended math *//* functions including cos, sin, tan, sec, csc, cot, acos, *//* asin, atan, asec, acsc, acot, cosh, sinh, tanh, sech, *//* csch, coth, acosh, asinh, atanh, asech, acsch, acoth, *//* mod, exp, log, log10, sqrt, pi, deg-rad, rad-deg, *//* deg-grad, grad-deg, **, and round. *//* *//* Principal Programmer(s): *//* Brian L. Donnell *//* *//* Contributing Programmer(s): *//* Gary D. Riley *//* *//* Revision History: *//* *//*************************************************************/#include "setup.h"#include "argacces.h"#include "envrnmnt.h"#include "extnfunc.h"#include "router.h"#include "emathfun.h"#if EX_MATH#include <math.h>/***************//* DEFINITIONS *//***************/#ifndef PI#define PI 3.14159265358979323846#endif#ifndef PID2#define PID2 1.57079632679489661923 /* PI divided by 2 */#endif#define SMALLEST_ALLOWED_NUMBER 1e-15#define dtrunc(x) (((x) < 0.0) ? ceil(x) : floor(x))/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/ static int SingleNumberCheck(void *,char *,double *); static int TestProximity(double,double); static void DomainErrorMessage(void *,char *); static void ArgumentOverflowErrorMessage(void *,char *); static void SingularityErrorMessage(void *,char *); static double genacosh(double); static double genasinh(double); static double genatanh(double); static double genasech(double); static double genacsch(double); static double genacoth(double);/************************************************//* ExtendedMathFunctionDefinitions: Initializes *//* the extended math functions. *//************************************************/globle void ExtendedMathFunctionDefinitions( void *theEnv) {#if ! RUN_TIME EnvDefineFunction2(theEnv,"cos", 'd', PTIEF CosFunction, "CosFunction", "11n"); EnvDefineFunction2(theEnv,"sin", 'd', PTIEF SinFunction, "SinFunction", "11n"); EnvDefineFunction2(theEnv,"tan", 'd', PTIEF TanFunction, "TanFunction", "11n"); EnvDefineFunction2(theEnv,"sec", 'd', PTIEF SecFunction, "SecFunction", "11n"); EnvDefineFunction2(theEnv,"csc", 'd', PTIEF CscFunction, "CscFunction", "11n"); EnvDefineFunction2(theEnv,"cot", 'd', PTIEF CotFunction, "CotFunction", "11n"); EnvDefineFunction2(theEnv,"acos", 'd', PTIEF AcosFunction, "AcosFunction", "11n"); EnvDefineFunction2(theEnv,"asin", 'd', PTIEF AsinFunction, "AsinFunction", "11n"); EnvDefineFunction2(theEnv,"atan", 'd', PTIEF AtanFunction, "AtanFunction", "11n"); EnvDefineFunction2(theEnv,"asec", 'd', PTIEF AsecFunction, "AsecFunction", "11n"); EnvDefineFunction2(theEnv,"acsc", 'd', PTIEF AcscFunction, "AcscFunction", "11n"); EnvDefineFunction2(theEnv,"acot", 'd', PTIEF AcotFunction, "AcotFunction", "11n"); EnvDefineFunction2(theEnv,"cosh", 'd', PTIEF CoshFunction, "CoshFunction", "11n"); EnvDefineFunction2(theEnv,"sinh", 'd', PTIEF SinhFunction, "SinhFunction", "11n"); EnvDefineFunction2(theEnv,"tanh", 'd', PTIEF TanhFunction, "TanhFunction", "11n"); EnvDefineFunction2(theEnv,"sech", 'd', PTIEF SechFunction, "SechFunction", "11n"); EnvDefineFunction2(theEnv,"csch", 'd', PTIEF CschFunction, "CschFunction", "11n"); EnvDefineFunction2(theEnv,"coth", 'd', PTIEF CothFunction, "CothFunction", "11n"); EnvDefineFunction2(theEnv,"acosh", 'd', PTIEF AcoshFunction, "AcoshFunction", "11n"); EnvDefineFunction2(theEnv,"asinh", 'd', PTIEF AsinhFunction, "AsinhFunction", "11n"); EnvDefineFunction2(theEnv,"atanh", 'd', PTIEF AtanhFunction, "AtanhFunction", "11n"); EnvDefineFunction2(theEnv,"asech", 'd', PTIEF AsechFunction, "AsechFunction", "11n"); EnvDefineFunction2(theEnv,"acsch", 'd', PTIEF AcschFunction, "AcschFunction", "11n"); EnvDefineFunction2(theEnv,"acoth", 'd', PTIEF AcothFunction, "AcothFunction", "11n"); EnvDefineFunction2(theEnv,"mod", 'n', PTIEF ModFunction, "ModFunction", "22n"); EnvDefineFunction2(theEnv,"exp", 'd', PTIEF ExpFunction, "ExpFunction", "11n"); EnvDefineFunction2(theEnv,"log", 'd', PTIEF LogFunction, "LogFunction", "11n"); EnvDefineFunction2(theEnv,"log10", 'd', PTIEF Log10Function, "Log10Function", "11n"); EnvDefineFunction2(theEnv,"sqrt", 'd', PTIEF SqrtFunction, "SqrtFunction", "11n"); EnvDefineFunction2(theEnv,"pi", 'd', PTIEF PiFunction, "PiFunction", "00"); EnvDefineFunction2(theEnv,"deg-rad", 'd', PTIEF DegRadFunction, "DegRadFunction", "11n"); EnvDefineFunction2(theEnv,"rad-deg", 'd', PTIEF RadDegFunction, "RadDegFunction", "11n"); EnvDefineFunction2(theEnv,"deg-grad", 'd', PTIEF DegGradFunction, "DegGradFunction", "11n"); EnvDefineFunction2(theEnv,"grad-deg", 'd', PTIEF GradDegFunction, "GradDegFunction", "11n"); EnvDefineFunction2(theEnv,"**", 'd', PTIEF PowFunction, "PowFunction", "22n"); EnvDefineFunction2(theEnv,"round", 'g', PTIEF RoundFunction, "RoundFunction", "11n");#else#if MAC_MCW || IBM_MCW || MAC_XCD#pragma unused(theEnv)#endif#endif }/************************************************************//* SingleNumberCheck: Retrieves the numeric argument for *//* extended math functions which expect a single floating *//* point argument. *//************************************************************/static int SingleNumberCheck( void *theEnv, char *functionName, double *theNumber) { DATA_OBJECT theValue; if (EnvArgCountCheck(theEnv,functionName,EXACTLY,1) == -1) return(FALSE); if (EnvArgTypeCheck(theEnv,functionName,1,FLOAT,&theValue) == FALSE) return(FALSE); *theNumber = DOToDouble(theValue); return(TRUE); }/**************************************************************//* TestProximity: Returns TRUE if the specified number falls *//* within the specified range, otherwise FALSE is returned. *//**************************************************************/static int TestProximity( double theNumber, double range) { if ((theNumber >= (- range)) && (theNumber <= range)) return TRUE; else return FALSE; }/********************************************************//* DomainErrorMessage: Generic error message used when *//* a domain error is detected during a call to one of *//* the extended math functions. *//********************************************************/static void DomainErrorMessage( void *theEnv, char *functionName) { PrintErrorID(theEnv,"EMATHFUN",1,FALSE); EnvPrintRouter(theEnv,WERROR,"Domain error for "); EnvPrintRouter(theEnv,WERROR,functionName); EnvPrintRouter(theEnv,WERROR," function.\n"); SetHaltExecution(theEnv,TRUE); SetEvaluationError(theEnv,TRUE); }/************************************************************//* ArgumentOverflowErrorMessage: Generic error message used *//* when an argument overflow is detected during a call to *//* one of the extended math functions. *//************************************************************/static void ArgumentOverflowErrorMessage( void *theEnv, char *functionName) { PrintErrorID(theEnv,"EMATHFUN",2,FALSE); EnvPrintRouter(theEnv,WERROR,"Argument overflow for "); EnvPrintRouter(theEnv,WERROR,functionName); EnvPrintRouter(theEnv,WERROR," function.\n"); SetHaltExecution(theEnv,TRUE); SetEvaluationError(theEnv,TRUE); }/************************************************************//* SingularityErrorMessage: Generic error message used when *//* a singularity is detected during a call to one of the *//* extended math functions. *//************************************************************/static void SingularityErrorMessage( void *theEnv, char *functionName) { PrintErrorID(theEnv,"EMATHFUN",3,FALSE); EnvPrintRouter(theEnv,WERROR,"Singularity at asymptote in "); EnvPrintRouter(theEnv,WERROR,functionName); EnvPrintRouter(theEnv,WERROR," function.\n"); SetHaltExecution(theEnv,TRUE); SetEvaluationError(theEnv,TRUE); }/*************************************//* CosFunction: H/L access routine *//* for the cos function. *//*************************************/globle double CosFunction( void *theEnv) { double num; if (SingleNumberCheck(theEnv,"cos",&num) == FALSE) return(0.0); return(cos(num)); }/*************************************//* SinFunction: H/L access routine *//* for the sin function. *//*************************************/globle double SinFunction( void *theEnv) { double num; if (SingleNumberCheck(theEnv,"sin",&num) == FALSE) return(0.0); return(sin(num)); }/*************************************//* TanFunction: H/L access routine *//* for the tan function. *//*************************************/globle double TanFunction( void *theEnv) { double num, tv; if (SingleNumberCheck(theEnv,"tan",&num) == FALSE) return (0.0); tv = cos(num); if ((tv < SMALLEST_ALLOWED_NUMBER) && (tv > -SMALLEST_ALLOWED_NUMBER)) { SingularityErrorMessage(theEnv,"tan"); return(0.0); } return(sin(num) / tv); }/*************************************//* SecFunction: H/L access routine *//* for the sec function. *//*************************************/globle double SecFunction( void *theEnv) { double num, tv; if (SingleNumberCheck(theEnv,"sec",&num) == FALSE) return(0.0); tv = cos(num); if ((tv < SMALLEST_ALLOWED_NUMBER) && (tv > -SMALLEST_ALLOWED_NUMBER)) { SingularityErrorMessage(theEnv,"sec"); return(0.0); } return(1.0 / tv); }/*************************************//* CscFunction: H/L access routine *//* for the csc function. *//*************************************/globle double CscFunction( void *theEnv) { double num, tv; if (SingleNumberCheck(theEnv,"csc",&num) == FALSE) return(0.0); tv = sin(num); if ((tv < SMALLEST_ALLOWED_NUMBER) && (tv > -SMALLEST_ALLOWED_NUMBER)) { SingularityErrorMessage(theEnv,"csc"); return(0.0); } return(1.0 / tv); }/*************************************//* CotFunction: H/L access routine *//* for the cot function. *//*************************************/globle double CotFunction( void *theEnv) { double num, tv; if (SingleNumberCheck(theEnv,"cot",&num) == FALSE) return(0.0); tv = sin(num); if ((tv < SMALLEST_ALLOWED_NUMBER) && (tv > -SMALLEST_ALLOWED_NUMBER)) { SingularityErrorMessage(theEnv,"cot"); return(0.0); } return(cos(num) / tv); }/**************************************//* AcosFunction: H/L access routine *//* for the acos function. *//**************************************/globle double AcosFunction( void *theEnv) { double num; if (SingleNumberCheck(theEnv,"acos",&num) == FALSE) return(0.0); if ((num > 1.0) || (num < -1.0)) { DomainErrorMessage(theEnv,"acos"); return(0.0); } return(acos(num)); }/**************************************//* AsinFunction: H/L access routine *//* for the asin function. *//**************************************/globle double AsinFunction( void *theEnv) { double num; if (SingleNumberCheck(theEnv,"asin",&num) == FALSE) return(0.0); if ((num > 1.0) || (num < -1.0)) { DomainErrorMessage(theEnv,"asin"); return(0.0); } return(asin(num)); }/**************************************//* AtanFunction: H/L access routine *//* for the atan function. *//**************************************/globle double AtanFunction( void *theEnv) { double num; if (SingleNumberCheck(theEnv,"atan",&num) == FALSE) return(0.0); return(atan(num)); }/**************************************//* AsecFunction: H/L access routine *//* for the asec function. *//**************************************/globle double AsecFunction( void *theEnv) { double num; if (SingleNumberCheck(theEnv,"asec",&num) == FALSE) return(0.0); if ((num < 1.0) && (num > -1.0)) { DomainErrorMessage(theEnv,"asec"); return(0.0); } num = 1.0 / num; return(acos(num)); }/**************************************//* AcscFunction: H/L access routine *//* for the acsc function. *//**************************************/globle double AcscFunction( void *theEnv) { double num; if (SingleNumberCheck(theEnv,"acsc",&num) == FALSE) return(0.0); if ((num < 1.0) && (num > -1.0)) { DomainErrorMessage(theEnv,"acsc"); return(0.0); } num = 1.0 / num; return(asin(num)); }/**************************************//* AcotFunction: H/L access routine *//* for the acot function. *//**************************************/globle double AcotFunction( void *theEnv) { double num; if (SingleNumberCheck(theEnv,"acot",&num) == FALSE) return(0.0); if (TestProximity(num,1e-25) == TRUE) return(PID2); num = 1.0 / num; return(atan(num)); }/**************************************//* CoshFunction: H/L access routine *//* for the cosh function. *//**************************************/globle double CoshFunction( void *theEnv) { double num; if (SingleNumberCheck(theEnv,"cosh",&num) == FALSE) return(0.0); return(cosh(num)); }/**************************************//* SinhFunction: H/L access routine *//* for the sinh function. *//**************************************/globle double SinhFunction( void *theEnv) { double num; if (SingleNumberCheck(theEnv,"sinh",&num) == FALSE) return(0.0); return(sinh(num)); }/**************************************//* TanhFunction: H/L access routine *//* for the tanh function. *//**************************************/globle double TanhFunction( void *theEnv) { double num; if (SingleNumberCheck(theEnv,"tanh",&num) == FALSE) return(0.0); return(tanh(num)); }/**************************************//* SechFunction: H/L access routine *//* for the sech function. *//**************************************/globle double SechFunction( void *theEnv) { double num; if (SingleNumberCheck(theEnv,"sech",&num) == FALSE) return(0.0); return(1.0 / cosh(num)); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -