📄 bmathfun.c
字号:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.05 04/09/97 */ /* */ /* BASIC MATH FUNCTIONS MODULE */ /*******************************************************//*************************************************************//* Purpose: Contains the code for numerous basic math *//* functions including +, *, -, /, integer, float, div, *//* abs,set-auto-float-dividend, get-auto-float-dividend, *//* min, and max. *//* *//* Principal Programmer(s): *//* Gary D. Riley *//* *//* Contributing Programmer(s): *//* *//* Revision History: *//* *//*************************************************************/#define _BMATHFUN_SOURCE_#include <stdio.h>#define _CLIPS_STDIO_#include "setup.h"#include "exprnpsr.h"#include "argacces.h"#include "router.h"#include "bmathfun.h"/***************************************//* LOCAL INTERNAL VARIABLE DEFINITIONS *//***************************************/ static BOOLEAN AutoFloatDividend = CLIPS_TRUE;/***************************************************************//* BasicMathFunctionDefinitions: Defines basic math functions. *//***************************************************************/globle VOID BasicMathFunctionDefinitions() { #if ! RUN_TIME DefineFunction2("+", 'n',PTIF AdditionFunction, "AdditionFunction", "2*n"); DefineFunction2("*", 'n', PTIF MultiplicationFunction, "MultiplicationFunction", "2*n"); DefineFunction2("-", 'n', PTIF SubtractionFunction, "SubtractionFunction", "2*n"); DefineFunction2("/", 'n', PTIF DivisionFunction, "DivisionFunction", "2*n"); DefineFunction2("div", 'l', PTIF DivFunction, "DivFunction", "2*n"); DefineFunction2("set-auto-float-dividend", 'b', SetAutoFloatDividendCommand, "SetAutoFloatDividendCommand", "11"); DefineFunction2("get-auto-float-dividend", 'b', GetAutoFloatDividendCommand, "GetAutoFloatDividendCommand", "00"); DefineFunction2("integer", 'l', PTIF IntegerFunction, "IntegerFunction", "11n"); DefineFunction2("float", 'd', PTIF FloatFunction, "FloatFunction", "11n"); DefineFunction2("abs", 'n', PTIF AbsFunction, "AbsFunction", "11n"); DefineFunction2("min", 'n', PTIF MinFunction, "MinFunction", "2*n"); DefineFunction2("max", 'n', PTIF MaxFunction, "MaxFunction", "2*n");#endif }/**********************************//* AdditionFunction: CLIPS access *//* routine for the + function. *//**********************************/globle VOID AdditionFunction(returnValue) DATA_OBJECT_PTR returnValue; { double ftotal = 0.0; long ltotal = 0L; BOOLEAN useFloatTotal = CLIPS_FALSE; EXPRESSION *theExpression; DATA_OBJECT theArgument; int pos = 1; /*=================================================*/ /* Loop through each of the arguments adding it to */ /* a running total. If a floating point number is */ /* encountered, then do all subsequent operations */ /* using floating point values. */ /*=================================================*/ theExpression = GetFirstArgument(); while (theExpression != NULL) { if (! GetNumericArgument(theExpression,"+",&theArgument,useFloatTotal,pos)) theExpression = NULL; else theExpression = GetNextArgument(theExpression); if (useFloatTotal) { ftotal += ValueToDouble(theArgument.value); } else { if (theArgument.type == INTEGER) { ltotal += ValueToLong(theArgument.value); } else { ftotal = (double) ltotal + ValueToDouble(theArgument.value); useFloatTotal = CLIPS_TRUE; } } pos++; } /*======================================================*/ /* If a floating point number was in the argument list, */ /* then return a float, otherwise return an integer. */ /*======================================================*/ if (useFloatTotal) { returnValue->type = FLOAT; returnValue->value = (VOID *) AddDouble(ftotal); } else { returnValue->type = INTEGER; returnValue->value = (VOID *) AddLong(ltotal); } }/****************************************//* MultiplicationFunction: CLIPS access *//* routine for the * function. *//****************************************/globle VOID MultiplicationFunction(returnValue) DATA_OBJECT_PTR returnValue; { double ftotal = 1.0; long ltotal = 1L; BOOLEAN useFloatTotal = CLIPS_FALSE; EXPRESSION *theExpression; DATA_OBJECT theArgument; int pos = 1; /*===================================================*/ /* Loop through each of the arguments multiplying it */ /* by a running product. If a floating point number */ /* is encountered, then do all subsequent operations */ /* using floating point values. */ /*===================================================*/ theExpression = GetFirstArgument(); while (theExpression != NULL) { if (! GetNumericArgument(theExpression,"*",&theArgument,useFloatTotal,pos)) theExpression = NULL; else theExpression = GetNextArgument(theExpression); if (useFloatTotal) { ftotal *= ValueToDouble(theArgument.value); } else { if (theArgument.type == INTEGER) { ltotal *= ValueToLong(theArgument.value); } else { ftotal = (double) ltotal * ValueToDouble(theArgument.value); useFloatTotal = CLIPS_TRUE; } } pos++; } /*======================================================*/ /* If a floating point number was in the argument list, */ /* then return a float, otherwise return an integer. */ /*======================================================*/ if (useFloatTotal) { returnValue->type = FLOAT; returnValue->value = (VOID *) AddDouble(ftotal); } else { returnValue->type = INTEGER; returnValue->value = (VOID *) AddLong(ltotal); } }/*************************************//* SubtractionFunction: CLIPS access *//* routine for the - function. *//*************************************/globle VOID SubtractionFunction(returnValue) DATA_OBJECT_PTR returnValue; { double ftotal = 0.0; long ltotal = 0L; BOOLEAN useFloatTotal = CLIPS_FALSE; EXPRESSION *theExpression; DATA_OBJECT theArgument; int pos = 1; /*=================================================*/ /* Get the first argument. This number which will */ /* be the starting total from which all subsequent */ /* arguments will subtracted. */ /*=================================================*/ theExpression = GetFirstArgument(); if (theExpression != NULL) { if (! GetNumericArgument(theExpression,"-",&theArgument,useFloatTotal,pos)) theExpression = NULL; else theExpression = GetNextArgument(theExpression); if (theArgument.type == INTEGER) { ltotal = ValueToLong(theArgument.value); } else { ftotal = ValueToDouble(theArgument.value); useFloatTotal = CLIPS_TRUE; } pos++; } /*===================================================*/ /* Loop through each of the arguments subtracting it */ /* from a running total. If a floating point number */ /* is encountered, then do all subsequent operations */ /* using floating point values. */ /*===================================================*/ while (theExpression != NULL) { if (! GetNumericArgument(theExpression,"-",&theArgument,useFloatTotal,pos)) theExpression = NULL; else theExpression = GetNextArgument(theExpression); if (useFloatTotal) { ftotal -= ValueToDouble(theArgument.value); } else { if (theArgument.type == INTEGER) { ltotal -= ValueToLong(theArgument.value); } else { ftotal = (double) ltotal - ValueToDouble(theArgument.value); useFloatTotal = CLIPS_TRUE; } } pos++; } /*======================================================*/ /* If a floating point number was in the argument list, */ /* then return a float, otherwise return an integer. */ /*======================================================*/ if (useFloatTotal) { returnValue->type = FLOAT; returnValue->value = (VOID *) AddDouble(ftotal); } else { returnValue->type = INTEGER; returnValue->value = (VOID *) AddLong(ltotal); } }/***********************************//* DivisionFunction: CLIPS access *//* routine for the / function. *//***********************************/globle VOID DivisionFunction(returnValue) DATA_OBJECT_PTR returnValue; { double ftotal = 1.0; long ltotal = 1L; BOOLEAN useFloatTotal = AutoFloatDividend; EXPRESSION *theExpression; DATA_OBJECT theArgument; int pos = 1; /*===================================================*/ /* Get the first argument. This number which will be */ /* the starting product from which all subsequent */ /* arguments will divide. If the auto float dividend */ /* feature is enable, then this number is converted */ /* to a float if it is an integer. */ /*===================================================*/ theExpression = GetFirstArgument(); if (theExpression != NULL) { if (! GetNumericArgument(theExpression,"/",&theArgument,useFloatTotal,pos)) theExpression = NULL; else theExpression = GetNextArgument(theExpression); if (theArgument.type == INTEGER) { ltotal = ValueToLong(theArgument.value); } else { ftotal = ValueToDouble(theArgument.value); useFloatTotal = CLIPS_TRUE; } pos++; } /*====================================================*/ /* Loop through each of the arguments dividing it */ /* into a running product. If a floating point number */ /* is encountered, then do all subsequent operations */ /* using floating point values. Each argument is */ /* checked to prevent a divide by zero error. */ /*====================================================*/ while (theExpression != NULL) { if (! GetNumericArgument(theExpression,"/",&theArgument,useFloatTotal,pos)) theExpression = NULL; else theExpression = GetNextArgument(theExpression); if ((theArgument.type == INTEGER) ? (ValueToLong(theArgument.value) == 0L) : ((theArgument.type == FLOAT) ? ValueToDouble(theArgument.value) == 0.0 : CLIPS_FALSE)) { DivideByZeroErrorMessage("/"); SetHaltExecution(CLIPS_TRUE); SetEvaluationError(CLIPS_TRUE); returnValue->type = FLOAT; returnValue->value = (VOID *) AddDouble(1.0); return; } if (useFloatTotal) { ftotal /= ValueToDouble(theArgument.value); } else { if (theArgument.type == INTEGER) { ltotal /= ValueToLong(theArgument.value); } else { ftotal = (double) ltotal / ValueToDouble(theArgument.value); useFloatTotal = CLIPS_TRUE; } } pos++; } /*======================================================*/ /* If a floating point number was in the argument list, */ /* then return a float, otherwise return an integer. */ /*======================================================*/ if (useFloatTotal) { returnValue->type = FLOAT; returnValue->value = (VOID *) AddDouble(ftotal); } else { returnValue->type = INTEGER; returnValue->value = (VOID *) AddLong(ltotal); } }/*************************************//* DivFunction: CLIPS access routine *//* for the div function. *//*************************************/globle long DivFunction() { long total = 1L; EXPRESSION *theExpression; DATA_OBJECT theArgument; int pos = 1; long theNumber; /*===================================================*/ /* Get the first argument. This number which will be */ /* the starting product from which all subsequent */ /* arguments will divide. */ /*===================================================*/ theExpression = GetFirstArgument(); if (theExpression != NULL) { if (! GetNumericArgument(theExpression,"div",&theArgument,CLIPS_FALSE,pos)) theExpression = NULL; else theExpression = GetNextArgument(theExpression); if (theArgument.type == INTEGER) { total = ValueToLong(theArgument.value); } else { total = (long) ValueToDouble(theArgument.value); } pos++; } /*=====================================================*/ /* Loop through each of the arguments dividing it into */ /* a running product. Floats are converted to integers */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -