⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bmathfun.c

📁 clips源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
   /*******************************************************/   /*      "C" Language Integrated Production System      */   /*                                                     */   /*             CLIPS Version 6.24  06/05/06            */   /*                                                     */   /*             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:                                         *//*      6.23: Correction for FalseSymbol/TrueSymbol. DR0859  *//*                                                           *//*      6.24: Renamed BOOLEAN macro type to intBool.         *//*                                                           *//*************************************************************/#define _BMATHFUN_SOURCE_#include <stdio.h>#define _STDIO_INCLUDED_#include "setup.h"#include "argacces.h"#include "envrnmnt.h"#include "exprnpsr.h"#include "router.h"#include "bmathfun.h"#define BMATHFUN_DATA 6struct basicMathFunctionData  {    intBool AutoFloatDividend;  };#define BasicMathFunctionData(theEnv) ((struct basicMathFunctionData *) GetEnvironmentData(theEnv,BMATHFUN_DATA))/***************************************************************//* BasicMathFunctionDefinitions: Defines basic math functions. *//***************************************************************/globle void BasicMathFunctionDefinitions(  void *theEnv)  {      AllocateEnvironmentData(theEnv,BMATHFUN_DATA,sizeof(struct basicMathFunctionData),NULL);      BasicMathFunctionData(theEnv)->AutoFloatDividend = TRUE;#if ! RUN_TIME   EnvDefineFunction2(theEnv,"+", 'n',PTIEF AdditionFunction, "AdditionFunction", "2*n");   EnvDefineFunction2(theEnv,"*", 'n', PTIEF MultiplicationFunction, "MultiplicationFunction", "2*n");   EnvDefineFunction2(theEnv,"-", 'n', PTIEF SubtractionFunction, "SubtractionFunction", "2*n");       EnvDefineFunction2(theEnv,"/", 'n', PTIEF DivisionFunction, "DivisionFunction", "2*n");   EnvDefineFunction2(theEnv,"div", 'g', PTIEF DivFunction, "DivFunction", "2*n");   EnvDefineFunction2(theEnv,"set-auto-float-dividend", 'b',                   SetAutoFloatDividendCommand, "SetAutoFloatDividendCommand", "11");   EnvDefineFunction2(theEnv,"get-auto-float-dividend", 'b',                  GetAutoFloatDividendCommand, "GetAutoFloatDividendCommand", "00");   EnvDefineFunction2(theEnv,"integer", 'g', PTIEF IntegerFunction, "IntegerFunction", "11n");   EnvDefineFunction2(theEnv,"float", 'd', PTIEF FloatFunction, "FloatFunction", "11n");   EnvDefineFunction2(theEnv,"abs", 'n', PTIEF AbsFunction, "AbsFunction", "11n");   EnvDefineFunction2(theEnv,"min", 'n', PTIEF MinFunction, "MinFunction", "2*n");   EnvDefineFunction2(theEnv,"max", 'n', PTIEF MaxFunction, "MaxFunction", "2*n");#endif  }/**********************************//* AdditionFunction: H/L access   *//*   routine for the + function.  *//**********************************/globle void AdditionFunction(  void *theEnv,  DATA_OBJECT_PTR returnValue)  {   double ftotal = 0.0;   long long ltotal = 0LL;   intBool useFloatTotal = 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(theEnv,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 = 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 *) EnvAddDouble(theEnv,ftotal);     }   else     {      returnValue->type = INTEGER;      returnValue->value = (void *) EnvAddLong(theEnv,ltotal);     }  }/****************************************//* MultiplicationFunction: CLIPS access *//*   routine for the * function.        *//****************************************/globle void MultiplicationFunction(  void *theEnv,  DATA_OBJECT_PTR returnValue)  {   double ftotal = 1.0;   long long ltotal = 1LL;   intBool useFloatTotal = 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(theEnv,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 = 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 *) EnvAddDouble(theEnv,ftotal);     }   else     {      returnValue->type = INTEGER;      returnValue->value = (void *) EnvAddLong(theEnv,ltotal);     }  }/*************************************//* SubtractionFunction: CLIPS access *//*   routine for the - function.     *//*************************************/globle void SubtractionFunction(  void *theEnv,  DATA_OBJECT_PTR returnValue)  {   double ftotal = 0.0;   long long ltotal = 0LL;   intBool useFloatTotal = 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(theEnv,theExpression,"-",&theArgument,useFloatTotal,pos)) theExpression = NULL;      else theExpression = GetNextArgument(theExpression);      if (theArgument.type == INTEGER)        { ltotal = ValueToLong(theArgument.value); }      else        {         ftotal = ValueToDouble(theArgument.value);         useFloatTotal = 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(theEnv,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 = 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 *) EnvAddDouble(theEnv,ftotal);     }   else     {      returnValue->type = INTEGER;      returnValue->value = (void *) EnvAddLong(theEnv,ltotal);     }  }/***********************************//* DivisionFunction:  CLIPS access *//*   routine for the / function.   *//***********************************/globle void DivisionFunction(  void *theEnv,  DATA_OBJECT_PTR returnValue)  {   double ftotal = 1.0;   long long ltotal = 1LL;   intBool useFloatTotal;   EXPRESSION *theExpression;   DATA_OBJECT theArgument;   int pos = 1;   useFloatTotal = BasicMathFunctionData(theEnv)->AutoFloatDividend;      /*===================================================*/   /* 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(theEnv,theExpression,"/",&theArgument,useFloatTotal,pos)) theExpression = NULL;      else theExpression = GetNextArgument(theExpression);      if (theArgument.type == INTEGER)        { ltotal = ValueToLong(theArgument.value); }      else        {         ftotal = ValueToDouble(theArgument.value);         useFloatTotal = 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(theEnv,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 : FALSE))        {         DivideByZeroErrorMessage(theEnv,"/");         SetHaltExecution(theEnv,TRUE);         SetEvaluationError(theEnv,TRUE);         returnValue->type = FLOAT;         returnValue->value = (void *) EnvAddDouble(theEnv,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 = 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 *) EnvAddDouble(theEnv,ftotal);     }   else     {      returnValue->type = INTEGER;      returnValue->value = (void *) EnvAddLong(theEnv,ltotal);     }  }/*************************************//* DivFunction: H/L access routine   *//*   for the div function.           *//*************************************/globle long long DivFunction(  void *theEnv)  {   long long total = 1LL;   EXPRESSION *theExpression;   DATA_OBJECT theArgument;   int pos = 1;   long 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(theEnv,theExpression,"div",&theArgument,FALSE,pos)) theExpression = NULL;      else theExpression = GetNextArgument(theExpression);      if (theArgument.type == INTEGER)        { total = ValueToLong(theArgument.value); }      else        { total = (long long) ValueToDouble(theArgument.value); }      pos++;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -